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