| rev | 
   line source | 
| 
bsw/jbe@4
 | 
     1 #include <stdlib.h>
 | 
| 
bsw/jbe@4
 | 
     2 #include <stdio.h>
 | 
| 
bsw/jbe@4
 | 
     3 #include <libpq-fe.h>
 | 
| 
bsw/jbe@4
 | 
     4 #include <string.h>
 | 
| 
bsw/jbe@4
 | 
     5 #include <regex.h>
 | 
| 
bsw/jbe@4
 | 
     6 #include <sys/types.h>
 | 
| 
bsw/jbe@4
 | 
     7 #include <sys/stat.h>
 | 
| 
bsw/jbe@4
 | 
     8 #include <unistd.h>
 | 
| 
bsw/jbe@4
 | 
     9 
 | 
| 
bsw/jbe@4
 | 
    10 #ifndef GETPIC_CONNINFO
 | 
| 
bsw/jbe@4
 | 
    11 #define GETPIC_CONNINFO "dbname=liquid_feedback"
 | 
| 
bsw/jbe@4
 | 
    12 #endif
 | 
| 
bsw/jbe@4
 | 
    13 
 | 
| 
bsw/jbe@4
 | 
    14 #ifndef GETPIC_DEFAULT_AVATAR
 | 
| 
bsw/jbe@4
 | 
    15 #define GETPIC_DEFAULT_AVATAR "/opt/liquid_feedback_testing/app/static/avatar.jpg"
 | 
| 
bsw/jbe@4
 | 
    16 #endif
 | 
| 
bsw/jbe@4
 | 
    17 
 | 
| 
bsw/jbe@4
 | 
    18 int main(int argc, const char * const *argv) {
 | 
| 
bsw/jbe@4
 | 
    19 
 | 
| 
bsw/jbe@4
 | 
    20   char *args_string;
 | 
| 
bsw/jbe@4
 | 
    21   char *member_id;
 | 
| 
bsw/jbe@4
 | 
    22   char *image_type;
 | 
| 
bsw/jbe@52
 | 
    23   const char *sql_member_image_params[2];
 | 
| 
bsw/jbe@4
 | 
    24 
 | 
| 
bsw@871
 | 
    25 #ifndef PUBLIC_ACCESS
 | 
| 
jbe@1108
 | 
    26 #ifdef PUBLIC_AVATAR_ACCESS
 | 
| 
jbe@1108
 | 
    27   int authorization_required = 0;
 | 
| 
jbe@1108
 | 
    28 #endif
 | 
| 
bsw/jbe@5
 | 
    29   char *cookies;
 | 
| 
bsw/jbe@5
 | 
    30   regex_t session_ident_regex;
 | 
| 
bsw/jbe@4
 | 
    31   ssize_t start, length;
 | 
| 
bsw/jbe@5
 | 
    32   regmatch_t session_ident_regmatch[3];
 | 
| 
bsw/jbe@4
 | 
    33   char *session_ident;
 | 
| 
bsw/jbe@52
 | 
    34   const char *sql_session_params[1];
 | 
| 
bsw@871
 | 
    35 #endif
 | 
| 
bsw/jbe@4
 | 
    36 
 | 
| 
bsw/jbe@5
 | 
    37   PGconn *conn;
 | 
| 
bsw/jbe@5
 | 
    38   PGresult *dbr;
 | 
| 
bsw/jbe@4
 | 
    39 
 | 
| 
bsw/jbe@4
 | 
    40   args_string = getenv("QUERY_STRING");
 | 
| 
bsw@873
 | 
    41   if (!args_string) {
 | 
| 
bsw@873
 | 
    42     fputs("Status: 403 Access Denied\n\n", stdout);
 | 
| 
bsw@873
 | 
    43     return 0;
 | 
| 
bsw@873
 | 
    44   }
 | 
| 
jbe@1108
 | 
    45 
 | 
| 
jbe@1108
 | 
    46   member_id   = strtok(args_string, "+");
 | 
| 
jbe@1108
 | 
    47   image_type  = strtok(NULL, "+");
 | 
| 
jbe@1108
 | 
    48   if (!member_id || !image_type) {
 | 
| 
bsw/jbe@4
 | 
    49     fputs("Status: 403 Access Denied\n\n", stdout);
 | 
| 
bsw/jbe@4
 | 
    50     return 0;
 | 
| 
bsw/jbe@4
 | 
    51   }
 | 
| 
bsw/jbe@4
 | 
    52   sql_member_image_params[0] = member_id;
 | 
| 
bsw/jbe@4
 | 
    53   sql_member_image_params[1] = image_type;
 | 
| 
bsw/jbe@4
 | 
    54 
 | 
| 
bsw@871
 | 
    55 #ifndef PUBLIC_ACCESS
 | 
| 
jbe@1108
 | 
    56 #ifdef PUBLIC_AVATAR_ACCESS
 | 
| 
jbe@1108
 | 
    57   if (strcmp(image_type, "avatar")) {
 | 
| 
jbe@1108
 | 
    58     authorization_required = 1;
 | 
| 
jbe@1108
 | 
    59 #endif
 | 
| 
jbe@1108
 | 
    60     cookies = getenv("HTTP_COOKIE");
 | 
| 
jbe@1108
 | 
    61     if (!args_string || !cookies) {
 | 
| 
jbe@1108
 | 
    62       fputs("Status: 403 Access Denied\n\n", stdout);
 | 
| 
jbe@1108
 | 
    63       return 0;
 | 
| 
jbe@1108
 | 
    64     }
 | 
| 
jbe@1108
 | 
    65     if (regcomp(&session_ident_regex, "(^|[; \t])liquid_feedback_session=([0-9A-Za-z]+)", REG_EXTENDED) != 0) {
 | 
| 
jbe@1108
 | 
    66       // shouldn't happen
 | 
| 
jbe@1108
 | 
    67       abort();
 | 
| 
jbe@1108
 | 
    68     }
 | 
| 
jbe@1108
 | 
    69     if (regexec(&session_ident_regex, cookies, 3, session_ident_regmatch, 0) != 0) {
 | 
| 
jbe@1108
 | 
    70       fputs("Status: 403 Access Denied\n\n", stdout);
 | 
| 
jbe@1108
 | 
    71       return 0;
 | 
| 
jbe@1108
 | 
    72     }
 | 
| 
jbe@1108
 | 
    73     start = session_ident_regmatch[2].rm_so;
 | 
| 
jbe@1108
 | 
    74     length = session_ident_regmatch[2].rm_eo - session_ident_regmatch[2].rm_so;
 | 
| 
jbe@1108
 | 
    75     session_ident = malloc(length + 1);
 | 
| 
jbe@1108
 | 
    76     if (!session_ident) abort();  // shouldn't happen
 | 
| 
jbe@1108
 | 
    77     strncpy(session_ident, cookies + start, length);
 | 
| 
jbe@1108
 | 
    78     session_ident[length] = 0;
 | 
| 
jbe@1108
 | 
    79     sql_session_params[0] = session_ident;
 | 
| 
jbe@1108
 | 
    80 #ifdef PUBLIC_AVATAR_ACCESS
 | 
| 
bsw/jbe@4
 | 
    81   }
 | 
| 
jbe@1108
 | 
    82 #endif
 | 
| 
bsw@874
 | 
    83 #endif
 | 
| 
bsw/jbe@4
 | 
    84 
 | 
| 
bsw/jbe@4
 | 
    85   conn = PQconnectdb(GETPIC_CONNINFO);
 | 
| 
bsw/jbe@4
 | 
    86   if (!conn) {
 | 
| 
bsw/jbe@4
 | 
    87     fputs("Could not create PGconn structure.\n", stderr);
 | 
| 
bsw/jbe@4
 | 
    88     return 1;
 | 
| 
bsw/jbe@4
 | 
    89   }
 | 
| 
bsw/jbe@4
 | 
    90   if (PQstatus(conn) != CONNECTION_OK) {
 | 
| 
bsw/jbe@4
 | 
    91     fputs(PQerrorMessage(conn), stderr);
 | 
| 
bsw/jbe@5
 | 
    92     PQfinish(conn);
 | 
| 
bsw/jbe@4
 | 
    93     return 1;
 | 
| 
bsw/jbe@4
 | 
    94   }
 | 
| 
bsw/jbe@4
 | 
    95 
 | 
| 
bsw@874
 | 
    96 #ifndef PUBLIC_ACCESS
 | 
| 
jbe@1108
 | 
    97 #ifdef PUBLIC_AVATAR_ACCESS
 | 
| 
jbe@1108
 | 
    98   if (authorization_required) {
 | 
| 
jbe@1108
 | 
    99 #endif
 | 
| 
jbe@1108
 | 
   100     dbr = PQexecParams(conn,
 | 
| 
jbe@1108
 | 
   101       "SELECT NULL FROM session JOIN member ON member.id = session.member_id WHERE session.ident = $1 AND member.active",
 | 
| 
jbe@1108
 | 
   102       1, NULL, sql_session_params, NULL, NULL, 0
 | 
| 
jbe@1108
 | 
   103     );
 | 
| 
jbe@1108
 | 
   104     if (PQresultStatus(dbr) != PGRES_TUPLES_OK) {
 | 
| 
jbe@1108
 | 
   105       fputs(PQresultErrorMessage(dbr), stderr);
 | 
| 
jbe@1108
 | 
   106       PQfinish(conn);
 | 
| 
jbe@1108
 | 
   107       return 1;
 | 
| 
jbe@1108
 | 
   108     }
 | 
| 
jbe@1108
 | 
   109     if (PQntuples(dbr) != 1) {
 | 
| 
jbe@1108
 | 
   110       fputs("Status: 403 Access Denied\n\n", stdout);
 | 
| 
jbe@1108
 | 
   111       PQfinish(conn);
 | 
| 
jbe@1108
 | 
   112       return 0;
 | 
| 
jbe@1108
 | 
   113     }
 | 
| 
jbe@1108
 | 
   114 #ifdef PUBLIC_AVATAR_ACCESS
 | 
| 
bsw/jbe@4
 | 
   115   }
 | 
| 
jbe@1108
 | 
   116 #endif
 | 
| 
bsw@871
 | 
   117 #endif
 | 
| 
bsw/jbe@4
 | 
   118 
 | 
| 
bsw/jbe@4
 | 
   119   dbr = PQexecParams(conn,
 | 
| 
bsw/jbe@4
 | 
   120     "SELECT content_type, data "
 | 
| 
bsw/jbe@4
 | 
   121     "FROM member_image "
 | 
| 
bsw/jbe@4
 | 
   122     "WHERE member_id = $1 "
 | 
| 
bsw/jbe@4
 | 
   123     "AND image_type = $2 "
 | 
| 
bsw/jbe@4
 | 
   124     "AND scaled "
 | 
| 
bsw/jbe@4
 | 
   125     "LIMIT 1;",
 | 
| 
bsw/jbe@4
 | 
   126     2, NULL, sql_member_image_params, NULL, NULL, 1
 | 
| 
bsw/jbe@4
 | 
   127   );
 | 
| 
bsw/jbe@4
 | 
   128   if (PQresultStatus(dbr) != PGRES_TUPLES_OK) {
 | 
| 
bsw/jbe@4
 | 
   129     fputs(PQresultErrorMessage(dbr), stderr);
 | 
| 
bsw/jbe@5
 | 
   130     PQfinish(conn);
 | 
| 
bsw/jbe@4
 | 
   131     return 1;
 | 
| 
bsw/jbe@4
 | 
   132   }
 | 
| 
bsw/jbe@4
 | 
   133   if (PQntuples(dbr) == 0) {
 | 
| 
bsw/jbe@4
 | 
   134     struct stat sb;
 | 
| 
bsw/jbe@4
 | 
   135     PQclear(dbr);
 | 
| 
bsw/jbe@4
 | 
   136     PQfinish(conn);
 | 
| 
bsw/jbe@4
 | 
   137     fputs("Content-Type: image/jpeg\n\n", stdout);
 | 
| 
bsw/jbe@4
 | 
   138     if (stat(GETPIC_DEFAULT_AVATAR, &sb)) return 1;
 | 
| 
bsw/jbe@5
 | 
   139     fprintf(stdout, "Content-Length: %i\n", (int)sb.st_size);
 | 
| 
bsw/jbe@4
 | 
   140     execl("/bin/cat", "cat", GETPIC_DEFAULT_AVATAR, NULL);
 | 
| 
bsw/jbe@4
 | 
   141     return 1;
 | 
| 
bsw/jbe@4
 | 
   142   } else {
 | 
| 
bsw/jbe@4
 | 
   143     if (PQnfields(dbr) < 0) {
 | 
| 
bsw/jbe@4
 | 
   144       fputs("Too few columns returned by database.\n", stderr);
 | 
| 
bsw/jbe@5
 | 
   145       PQfinish(conn);
 | 
| 
bsw/jbe@4
 | 
   146       return 1;
 | 
| 
bsw/jbe@4
 | 
   147     }
 | 
| 
bsw/jbe@4
 | 
   148     if (PQfformat(dbr, 0) != 1 || PQfformat(dbr, 1) != 1) {
 | 
| 
bsw/jbe@4
 | 
   149       fputs("Database did not return data in binary format.\n", stderr);
 | 
| 
bsw/jbe@5
 | 
   150       PQfinish(conn);
 | 
| 
bsw/jbe@4
 | 
   151       return 1;
 | 
| 
bsw/jbe@4
 | 
   152     }
 | 
| 
bsw/jbe@4
 | 
   153     if (PQgetisnull(dbr, 0, 0) || PQgetisnull(dbr, 0, 1)) {
 | 
| 
bsw/jbe@4
 | 
   154       fputs("Unexpected NULL in database result.\n", stderr);
 | 
| 
bsw/jbe@5
 | 
   155       PQfinish(conn);
 | 
| 
bsw/jbe@4
 | 
   156       return 1;
 | 
| 
bsw/jbe@4
 | 
   157     }
 | 
| 
bsw/jbe@52
 | 
   158     fprintf(stdout, "Content-Type: %s\n\n", PQgetvalue(dbr, 0, 0));
 | 
| 
bsw/jbe@4
 | 
   159     fwrite(PQgetvalue(dbr, 0, 1), PQgetlength(dbr, 0, 1), 1, stdout);
 | 
| 
bsw/jbe@4
 | 
   160   }
 | 
| 
bsw/jbe@4
 | 
   161   PQfinish(conn);
 | 
| 
bsw/jbe@4
 | 
   162   return 0;
 | 
| 
bsw/jbe@5
 | 
   163 
 | 
| 
bsw/jbe@4
 | 
   164 }
 |