//
// File .......... peek.c
// Author ........ Steve Haywood
// Version ....... 1.0
// Date .......... 26 Novemebr 2021
// Description ...
//   Very simple CGI peek application for single 32-bit reads. Provides
// status & error reporting back to the client side application.
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>

int main()
{
  char *querystring;
  char *paddr;
  char *pval;
  int fd;
  void *ptr;
  unsigned addr, page_addr, page_offset;
  unsigned page_size = sysconf(_SC_PAGESIZE);
  printf("Content-Type: text/plain;charset=us-ascii\n\n");
  querystring = getenv("QUERY_STRING");
  if (querystring) {
    pval = querystring;
    if (paddr = strtok_r(pval, "&", &pval)) {
//      if (pval) {
        fd = open("/dev/mem", O_RDWR);
        if (fd > 0) {
          addr = strtoul(paddr, NULL, 0);
          page_addr = (addr & ~(page_size - 1));
          page_offset = addr - page_addr;
          ptr = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, page_addr);
          if (ptr != MAP_FAILED) {
            printf("0x%08X",*((unsigned *)(ptr + page_offset)));
          } else printf("Error: Failed to mmap");
        } else printf("Error: Failed to open /dev/mem");
//      } else printf("Error: Data not found");
    } else printf("Error: Address not found");
  } else printf("Error: No QUERY_STRING");
}
