/** * Copyright (C) 2014 Aaron Ball * * Remoteinfo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Remoteinfo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with remoteinfo. If not, see . */ #include #include #include #define qsmax 512 /** * Searches the query string for the specified key, and copies the value * to the out variable. * * @param char* key Key to search the query string for * @param int len Maximum length of key and value (for security reasons) * @param char* out Pointer to output variable value will be copied to * * @return int Found (1), not found (0), or error (-1) */ int getqs(char* key, int len, char* out) { char* qs; char* val; int valstart; int i; // Get the query string qs = getenv("QUERY_STRING"); // Exit early if the query string was not found. if(qs == NULL) return -1; // Search for the key in the query string val = strstr(qs, key); // Exit early if the key/value was not found. if(val == NULL) return 0; i = 0; // Find the equals sign while(val[i] != '=') { // break if we hit a qs delimiter (&) if(val[i] == '&') return 0; // Break if we hit the maximum length (for security, to avoid buffer // overflows or overflow dumps. if((i + 1) == len) return 0; i++; } // Repoint the start of val val = &val[i + 1]; // Reset i to 0 i = 0; while(val[i] != '\0') { // break if we hit a qs delimiter (&) if(val[i] == '&') break; // Break if we hit the maximum length (for security, to avoid buffer // overflows or overflow dumps. if((i + 1) == len) break; // copy char in out[i] = val[i]; i++; } out[i] = '\0'; return 1; } void read_file(char* path, FILE* out) { FILE *f = fopen(path, "r"); fprintf(out, "
");

  char buf;
  while((buf = fgetc(f)) != EOF) {
    if(buf == '<') {
      // Print an html line break if we fine a newline
      fprintf(out, "<");
    } else {
      fprintf(out, "%c", buf);
    }
  }
  fprintf(out, "
"); fclose(f); } void stylesheet(char* path, FILE* out) { fprintf(out, "\n", path); } int print_html_header(FILE* out) { fprintf(out, "\n"); fprintf(out, "\n"); stylesheet("style.css", out); fprintf(out, "\n"); fprintf(out, "\n"); } void print_body(FILE* out) { char q[qsmax]; int found; char* reqvar; // Get value of q found = getqs("q", qsmax, q); if(found != 1) return; // All looks well, let's try to handle the query string. if(strcmp(q, "ip") == 0) { // IP request reqvar = getenv("REMOTE_ADDR"); if(reqvar == NULL) { fprintf(out, "ERROR: REMOTE_ADDR not set."); } else { fprintf(out, "%s", getenv("REMOTE_ADDR")); } } else if(strcmp(q, "agent") == 0) { // Useragent request reqvar = getenv("HTTP_USER_AGENT"); if(reqvar == NULL) { fprintf(out, "ERROR: HTTP_USER_AGENT not set."); } else { fprintf(out, "%s", getenv("HTTP_USER_AGENT")); } } fprintf(out, "\n"); } void print_html_footer(FILE* out) { fprintf(out, "\n\n"); } int main(int argc, char* argv[]) { // Print the content type header (very useful) fprintf(stdout, "Content-Type: text/html;\n\n"); // Check if "type" qs is specified, and handle appropriately if it is // This is for printing in different formats (eg: style html, json, etc) int found; char type[qsmax]; found = getqs("type", qsmax, type); if(found == 1) { // Prints the html header (, etc.) print_html_header(stdout); } print_body(stdout); // Annnnd the footer if(found == 1) { // Prints the html footer () print_html_footer(stdout); } return 0; }