liquid_feedback_frontend
view fastpath/getpic.c @ 4:80c215dbf076
Version alpha5
Many optical changes and improved usability
Support for different wiki-formatting-engines
Help system
Many optical changes and improved usability
Support for different wiki-formatting-engines
Help system
| author | bsw/jbe | 
|---|---|
| date | Thu Dec 10 12:00:00 2009 +0100 (2009-12-10) | 
| parents | |
| children | afd9f769c7ae | 
 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) {
    19   PGconn *conn;
    20   PGresult *dbr;
    22   char *cookies = getenv("HTTP_COOKIE");
    24   char *args_string;
    25   char *member_id;
    26   char *image_type;
    28   char *sql_session_params[1];
    29   char *sql_member_image_params[2];
    31   ssize_t start, length;
    33   char *session_ident;
    35   regex_t session_ident_regex;
    36   regmatch_t session_ident_regmatch[2];
    38   cookies = getenv("HTTP_COOKIE");
    40   args_string = getenv("QUERY_STRING");
    42   if (!cookies || !args_string) {
    43     fputs("Status: 403 Access Denied\n\n", stdout);
    44     return 0;
    45   }
    47   member_id   = strtok(args_string, "+");
    48   image_type  = strtok(NULL, "+");
    50   sql_member_image_params[0] = member_id;
    51   sql_member_image_params[1] = image_type;
    53   // get session from cookie
    55   // TODO improve regex to fit better
    56   if (regcomp(&session_ident_regex, "liquid_feedback_session=([a-zA-Z0-9]+)", REG_EXTENDED) != 0) {
    57     // shouldn't happen
    58     abort();
    59   }
    61   if (regexec(&session_ident_regex, cookies, 2, session_ident_regmatch, 0) != 0) {
    62     fputs("Status: 403 Access Denied\n\n", stdout);
    63     return 0;
    64   }
    66   start = session_ident_regmatch[1].rm_so;
    67   length = session_ident_regmatch[1].rm_eo - session_ident_regmatch[1].rm_so;
    69   session_ident = malloc(length + 1);
    71   strncpy(session_ident, cookies + start, length);
    73   session_ident[length] = 0;
    75   sql_session_params[0] = session_ident;
    78   // connect to database
    80   conn = PQconnectdb(GETPIC_CONNINFO);
    81   if (!conn) {
    82     fputs("Could not create PGconn structure.\n", stderr);
    83     return 1;
    84   }
    85   if (PQstatus(conn) != CONNECTION_OK) {
    86     fputs(PQerrorMessage(conn), stderr);
    87     return 1;
    88   }
    90   // check session
    91   dbr = PQexecParams(conn,
    92     "SELECT NULL FROM session JOIN member ON member.id = session.member_id WHERE session.ident = $1 AND member.active",
    93     1, NULL, sql_session_params, NULL, NULL, 0
    94   );
    96   if (PQresultStatus(dbr) != PGRES_TUPLES_OK) {
    97     fputs(PQresultErrorMessage(dbr), stderr);
    98     return 1;
    99   }
   101   if (PQntuples(dbr) != 1) {
   102     fputs("Status: 403 Access Denied\n\n", stdout);
   103     return 0;
   104   }
   107   // get picture
   108   dbr = PQexecParams(conn,
   109     "SELECT content_type, data "
   110     "FROM member_image "
   111     "WHERE member_id = $1 "
   112     "AND image_type = $2 "
   113     "AND scaled "
   114     "LIMIT 1;",
   115     2, NULL, sql_member_image_params, NULL, NULL, 1
   116   );
   118   if (PQresultStatus(dbr) != PGRES_TUPLES_OK) {
   119     fputs(PQresultErrorMessage(dbr), stderr);
   120 		return 1;
   121   }
   122   if (PQntuples(dbr) > 1) {
   123     return 1;
   124   }
   125   fputs("Cache-Control: private; max-age=86400\n", stdout);
   126   if (PQntuples(dbr) == 0) {
   127     struct stat sb;
   128     PQclear(dbr);
   129     PQfinish(conn);
   130     fputs("Content-Type: image/jpeg\n\n", stdout);
   131     if (stat(GETPIC_DEFAULT_AVATAR, &sb)) return 1;
   132     fprintf(stdout, "Content-Length: %i\n", sb.st_size);
   133     execl("/bin/cat", "cat", GETPIC_DEFAULT_AVATAR, NULL);
   134     return 1;
   135   } else {
   136     if (PQnfields(dbr) < 0) {
   137       fputs("Too few columns returned by database.\n", stderr);
   138       return 1;
   139     }
   140     if (PQfformat(dbr, 0) != 1 || PQfformat(dbr, 1) != 1) {
   141       fputs("Database did not return data in binary format.\n", stderr);
   142       return 1;
   143     }
   144     if (PQgetisnull(dbr, 0, 0) || PQgetisnull(dbr, 0, 1)) {
   145       fputs("Unexpected NULL in database result.\n", stderr);
   146       return 1;
   147     }
   148     fputs("Content-Type: ", stdout);
   149     fprintf(stdout, "Content-Length: %i\n", PQgetlength(dbr, 0, 1));
   150     fwrite(PQgetvalue(dbr, 0, 0), PQgetlength(dbr, 0, 0), 1, stdout);
   151     fputs("\n\n", stdout);
   152     fwrite(PQgetvalue(dbr, 0, 1), PQgetlength(dbr, 0, 1), 1, stdout);
   153   }
   154   PQclear(dbr);
   155   PQfinish(conn);
   156   return 0;
   157 }
