summaryrefslogtreecommitdiff
path: root/src/cgi.c
blob: b8ade617c1c1992dd655909e8f1bf8ee4d515765 (plain)
    1 /**
    2  * This CGI program renders the oper.io blog
    3  * Copyright (C) 2024 Aaron Ball <nullspoon@oper.io>
    4  *
    5  * This program is free software: you can redistribute it and/or modify
    6  * it under the terms of the GNU General Public License as published by
    7  * the Free Software Foundation, either version 3 of the License, or
    8  * (at your option) any later version.
    9  *
   10  * This program is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  * GNU General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU General Public License
   16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   17  */
   18 #include "cgi.h"
   19 
   20 void cgi_print_header(char* ctype, int status) {
   21   printf("Content-type: %s\n", ctype);
   22   printf("Status: %d\n", status);
   23   printf("\n");
   24 }
   25 
   26 void cgi_print_headers() {
   27   int i = 0;
   28   while(environ[i] != NULL) {
   29     if(strncmp(environ[i], "HTTP_", 5) == 0) {
   30       puts(environ[i]);
   31     }
   32     i++;
   33   }
   34 }
   35 
   36 char* cgi_remote_ip() {
   37   if(getenv("HTTP_X_FORWARDED_FOR"))
   38     return getenv("HTTP_X_FORWARDED_FOR");
   39   else
   40     return getenv("REMOTE_ADDR");
   41   return NULL;
   42 }
   43 
   44 char* cgi_user_agent() {
   45   if(getenv("HTTP_USER_AGENT"))
   46     return getenv("HTTP_USER_AGENT");
   47   return NULL;
   48 }
   49 
   50 int cgi_read_qs(struct querystring* q, char* buf) {
   51   // If query string is null, probably env var isn't set
   52   if(!q->qs)
   53     return EOF;
   54 
   55   int i = q->pos;
   56   while(q->qs[i] != '\0' && i < QS_MAX) {
   57     if(q->qs[i] == '=' || q->qs[i] == '&')
   58       break;
   59     i++;
   60   }
   61 
   62   // Copy section into buffer
   63   strncpy(buf, &q->qs[q->pos], i - q->pos);
   64   buf[i - q->pos] = '\0';
   65 
   66   // Advance start position to i + 1 to skip the current delimiter
   67   q->pos = i + 1;
   68 
   69   if(q->qs[i] == '\0')
   70     return EOF;
   71 
   72   return 0;
   73 }
   74 
   75 
   76 /**
   77  * cgi_qs_get_val:
   78  * Gets the value of the first occurrence of the requested key. Supports more
   79  * than one key to allow for easy backwards compatibility without re-traversing
   80  * the query string.
   81  *
   82  * @qs     Query string struct
   83  * @keys   Array of character arrays containing the query string keys
   84  * @out    Output buffer
   85  *
   86  * Returns 0 on success, and -1 on failure
   87  */
   88 int cgi_qs_get_val(struct querystring* qs, char** keys, char* out) {
   89   int i = 0;
   90   int res = 0;
   91   char buf[256];
   92 
   93   while((res = cgi_read_qs(qs, buf)) != EOF) {
   94     while(keys[i][0] != '\0') {
   95       if(strcmp(buf, keys[i]) == 0) {
   96         if(res == EOF)
   97           return -1;
   98         cgi_read_qs(qs, out);
   99         return 0;
  100       }
  101       i++;
  102     }
  103   }
  104   return -1;
  105 }

Generated by cgit