summaryrefslogtreecommitdiff
path: root/src/main.c
blob: 1bc49e7b2280f559b1441d8a217eb6c37680c3fa (plain)
    1 /**
    2  * Copyright (C) 2014 Aaron Ball <nullspoon@iohq.net>
    3  *
    4  * Remoteinfo is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 3 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * Remoteinfo is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with remoteinfo.  If not, see <http://www.gnu.org/licenses/>.
   16  */
   17 #include <stdio.h>
   18 #include <stdlib.h>
   19 #include <string.h>
   20 
   21 #define qsmax 512
   22 
   23 /**
   24  * Searches the query string for the specified key, and copies the value
   25  * to the out variable.
   26  *
   27  * @param char* key Key to search the query string for
   28  * @param int   len Maximum length of key and value (for security reasons)
   29  * @param char* out Pointer to output variable value will be copied to
   30  *
   31  * @return int Found (1), not found (0), or error (-1)
   32  */
   33 int getqs(char* key, int len, char* out) {
   34   char* qs;
   35   char* val;
   36   int valstart;
   37   int i;
   38 
   39   // Get the query string
   40   qs = getenv("QUERY_STRING");
   41 
   42   // Exit early if the query string was not found.
   43   if(qs == NULL) return -1;
   44 
   45   // Search for the key in the query string
   46   val = strstr(qs, key);
   47 
   48   // Exit early if the key/value was not found.
   49   if(val == NULL) return 0;
   50 
   51   i = 0;
   52   // Find the equals sign
   53   while(val[i] != '=') {
   54     // break if we hit a qs delimiter (&)
   55     if(val[i] == '&') return 0;
   56     // Break if we hit the maximum length (for security, to avoid buffer
   57     // overflows or overflow dumps.
   58     if((i + 1) == len) return 0;
   59     i++;
   60   }
   61   // Repoint the start of val
   62   val = &val[i + 1];
   63 
   64   // Reset i to 0
   65   i = 0;
   66   while(val[i] != '\0') {
   67     // break if we hit a qs delimiter (&)
   68     if(val[i] == '&') break;
   69     // Break if we hit the maximum length (for security, to avoid buffer
   70     // overflows or overflow dumps.
   71     if((i + 1) == len) break;
   72     // copy char in
   73     out[i] = val[i];
   74     i++;
   75   }
   76   out[i] = '\0';
   77   return 1;
   78 }
   79 
   80 
   81 void read_file(char* path, FILE* out) {
   82   FILE *f = fopen(path, "r");
   83 
   84   fprintf(out, "<pre>");
   85 
   86   char buf;
   87   while((buf = fgetc(f)) != EOF) {
   88     if(buf == '<') {
   89       // Print an html line break if we fine a newline
   90       fprintf(out, "&lt;");
   91     } else {
   92       fprintf(out, "%c", buf);
   93     }
   94   }
   95   fprintf(out, "</pre>");
   96 
   97   fclose(f);
   98 }
   99 
  100 void stylesheet(char* path, FILE* out) {
  101   fprintf(out, "<link rel=\"stylesheet\" ");
  102   fprintf(out, "type=\"text/css\" href=\"%s\" />\n", path);
  103 }
  104 
  105 int print_html_header(FILE* out) {
  106   fprintf(out, "<html>\n");
  107   fprintf(out, "<head>\n");
  108   stylesheet("style.css", out);
  109   fprintf(out, "</head>\n");
  110   fprintf(out, "<body>\n");
  111 }
  112 
  113 void print_body(FILE* out) {
  114   char q[qsmax];
  115   int found;
  116   char* reqvar;
  117 
  118   // Get value of q
  119   found = getqs("q", qsmax, q);
  120   if(found != 1) return;
  121 
  122   // All looks well, let's try to handle the query string.
  123   if(strcmp(q, "ip") == 0) {
  124     // IP request
  125     reqvar = getenv("REMOTE_ADDR");
  126     if(reqvar == NULL) {
  127       fprintf(out, "ERROR: REMOTE_ADDR not set.");
  128     } else {
  129       fprintf(out, "%s", getenv("REMOTE_ADDR"));
  130     }
  131   } else if(strcmp(q, "agent") == 0) {
  132     // Useragent request
  133     reqvar = getenv("HTTP_USER_AGENT");
  134     if(reqvar == NULL) {
  135       fprintf(out, "ERROR: HTTP_USER_AGENT not set.");
  136     } else {
  137       fprintf(out, "%s", getenv("HTTP_USER_AGENT"));
  138     }
  139   }
  140   fprintf(out, "\n");
  141 }
  142 
  143 
  144 void print_html_footer(FILE* out) {
  145   fprintf(out, "</body>\n</html>\n");
  146 }
  147 
  148 
  149 int main(int argc, char* argv[]) {
  150   // Print the content type header (very useful)
  151   fprintf(stdout, "Content-Type: text/html;\n\n");
  152 
  153   // Check if "type" qs is specified, and handle appropriately if it is
  154   // This is for printing in different formats (eg: style html, json, etc)
  155   int found;
  156   char type[qsmax];
  157   found = getqs("type", qsmax, type);
  158 
  159   if(found == 1) {
  160     // Prints the html header (<html><head>, etc.)
  161     print_html_header(stdout);
  162   }
  163 
  164   print_body(stdout);
  165   
  166   // Annnnd the footer
  167   if(found == 1) {
  168     // Prints the html footer (</body></html>)
  169     print_html_footer(stdout);
  170   }
  171 
  172   return 0;
  173 }

Generated by cgit