home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Magazine / wwwoffle-2.1.tar.gz / wwwoffle-2.1 / monitor.c < prev    next >
C/C++ Source or Header  |  1998-02-21  |  10KB  |  396 lines

  1. /***************************************
  2.   $Header: /home/amb/wwwoffle/RCS/monitor.c 1.8 1998/02/21 15:41:28 amb Exp $
  3.  
  4.   WWWOFFLE - World Wide Web Offline Explorer - Version 2.1.
  5.   A header file for all of the programs wwwoffle, wwwoffled.
  6.   ******************/ /******************
  7.   Written by Andrew M. Bishop
  8.  
  9.   This file Copyright 1998 Andrew M. Bishop
  10.   It may be distributed under the GNU Public License, version 2, or
  11.   any higher version.  See section COPYING of the GNU Public license
  12.   for conditions under which this file may be redistributed.
  13.   ***************************************/
  14.  
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19.  
  20. #include <unistd.h>
  21. #include <time.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <dirent.h>
  25. #include <fcntl.h>
  26.  
  27. #include "wwwoffle.h"
  28. #include "misc.h"
  29. #include "config.h"
  30. #include "errors.h"
  31.  
  32.  
  33. static void MonitorFormPage(int fd,char *args);
  34. static void MonitorFormParse(int fd,char *request_body);
  35. static void MonitorFormError(int fd,char *body);
  36. static void IllegalMonitorPage(int fd,char *path,char *args);
  37.  
  38.  
  39. /*++++++++++++++++++++++++++++++++++++++
  40.   Send to the client a page to allow monitoring using HTML.
  41.  
  42.   int fd The file descriptor of the client.
  43.  
  44.   char *path The path that was specified by the user.
  45.  
  46.   char *args The argument that was appended to the URL.
  47.  
  48.   char *request_body The body of the HTTP request.
  49.   ++++++++++++++++++++++++++++++++++++++*/
  50.  
  51. void MonitorPage(int fd,char *path,char *args,char *request_body)
  52. {
  53.  if(!strcmp("/monitor/",path))
  54.     MonitorFormPage(fd,args);
  55.  else if(!strcmp("/monitor-request/",path))
  56.     MonitorFormParse(fd,request_body);
  57.  else
  58.     IllegalMonitorPage(fd,path,args);
  59. }
  60.  
  61.  
  62. /*++++++++++++++++++++++++++++++++++++++
  63.   The form that the user enters the details on.
  64.  
  65.   int fd The file descriptor.
  66.  
  67.   char *args The arguments that were on the request for this URL.
  68.   ++++++++++++++++++++++++++++++++++++++*/
  69.  
  70. static void MonitorFormPage(int fd,char *args)
  71. {
  72.  char *head=
  73.  "HTTP/1.0 200 WWWOFFLE Monitor Form\r\n"
  74.  "Content-type: text/html\r\n"
  75.  "\r\n"
  76.  "<HTML>\n"
  77.  "<HEAD>\n"
  78.  "<TITLE>WWWOFFLE - Interactive Monitor Form</TITLE>\n"
  79.  "</HEAD>\n"
  80.  "<BODY>\n"
  81.  "<H1 align=center>WWWOFFLE Interactive Monitor Form</H1>\n"
  82.  "You can use this form to monitor any URL.\n"
  83.  "<p>\n"
  84.  "<form action=\"/monitor-request/\" method=post>\n"
  85.  "Monitor <input type=\"text\" name=\"url\" value=\"";
  86.  char *middle=
  87.  "\"size=60>\n"
  88.  "<br>\n";
  89.  char *tail1=
  90.  "<br>\n"
  91.  "<input type=\"submit\" value=\"Monitor Now\">\n"
  92.  "</form>\n";
  93.  char *tail2=
  94.  "</BODY>\n"
  95.  "</HTML>\n";
  96.  
  97.  write_string(fd,head);
  98.  if(args)
  99.    {
  100.     char *decargs=UrlDecode(args,0);
  101.     write_string(fd,decargs);
  102.     free(decargs);
  103.    }
  104.  write_string(fd,middle);
  105.  if(MonitorInterval<=0)
  106.     write_string(fd,"every time online\n");
  107.  else
  108.     write_formatted(fd,"every %d days\n",MonitorInterval);
  109.  write_string(fd,tail1);
  110.  if(!args)
  111.     write_string(fd,"<p align=center>[<a href=\"/\">Back to the Welcome page</a>]</p>\n");
  112.  write_string(fd,tail2);
  113. }
  114.  
  115.  
  116. /*++++++++++++++++++++++++++++++++++++++
  117.   Parse the reply from the form.
  118.  
  119.   int fd The file descriptor of the client.
  120.  
  121.   char *request_body The body of the HTTP request sent by the browser.
  122.   ++++++++++++++++++++++++++++++++++++++*/
  123.  
  124. static void MonitorFormParse(int fd,char *request_body)
  125. {
  126.  int i,mfd=-1;
  127.  char *copy,*url=NULL;
  128.  URL *Url;
  129.  
  130.  if(!request_body)
  131.    {
  132.     MonitorFormError(fd,NULL);
  133.     return;
  134.    }
  135.  
  136.  copy=(char*)malloc(strlen(request_body)+1);
  137.  strcpy(copy,request_body);
  138.  
  139.  for(i=0;copy[i];i++)
  140.    {
  141.     if(i!=0 && copy[i-1]=='&')
  142.        copy[i-1]=0;
  143.     if(i==0 || copy[i-1]==0)
  144.       {
  145.        if(!strncmp("url=",©[i],4))
  146.           url=©[i+4];
  147.       }
  148.    }
  149.  
  150.  if(url==NULL || *url==0)
  151.    {
  152.     MonitorFormError(fd,request_body);
  153.     free(copy);
  154.     return;
  155.    }
  156.  
  157.  url=UrlDecode(url,1);
  158.  Url=SplitURL(url);
  159.  
  160.  mfd=OpenMonitorSpoolFile(Url);
  161.  if(mfd==-1)
  162.     ServerError(fd,"Cannot open file to store monitor request");
  163.  else
  164.    {
  165.     char *head=
  166.     "HTTP/1.0 200 WWWOFFLE Monitor Requested\r\n"
  167.     "Content-type: text/html\r\n"
  168.     "\r\n"
  169.     "<HTML>\n"
  170.     "<HEAD>\n"
  171.     "<TITLE>WWWOFFLE - Monitor Requested</TITLE>\n"
  172.     "</HEAD>\n"
  173.     "<BODY>\n"
  174.     "<H1 align=center>WWWOFFLE Monitor Requested</H1>\n"
  175.     "<p align=center>\n"
  176.     "Your request for URL\n"
  177.     "<br><b><tt>\n";
  178.     char *tail=
  179.     "\n"
  180.     "</tt></b><br>\n"
  181.     "to be monitored has been recorded.\n"
  182.     "<br>\n"
  183.     "</BODY>\n"
  184.     "</HTML>\n";
  185.  
  186.     char *req=RequestURL(Url->name,NULL);
  187.     int ofd=OpenOutgoingSpoolFile(0);
  188.  
  189.     if(ofd==-1)
  190.        PrintMessage(Warning,"Cannot open outgoing spool file for monitored URL '%s' [%!s].",url);
  191.     else
  192.       {
  193.        write_string(ofd,req);
  194.  
  195.        CloseOutgoingSpoolFile(ofd,Url);
  196.       }
  197.  
  198.     write_string(mfd,req);
  199.  
  200.     write_string(fd,head);
  201.     write_string(fd,Url->name);
  202.     write_string(fd,tail);
  203.  
  204.     free(req);
  205.     close(mfd);
  206.    }
  207.  
  208.  free(copy);
  209.  
  210.  FreeURL(Url);
  211. }
  212.  
  213.  
  214. /*++++++++++++++++++++++++++++++++++++++
  215.   An error with the form.
  216.  
  217.   int fd The file descriptor.
  218.  
  219.   char *body The browser reply that the user entered.
  220.   ++++++++++++++++++++++++++++++++++++++*/
  221.  
  222. static void MonitorFormError(int fd,char *body)
  223. {
  224.  char *head=
  225.  "HTTP/1.0 404 WWWOFFLE Monitor Form Error\r\n"
  226.  "Content-type: text/html\r\n"
  227.  "\r\n"
  228.  "<HTML>\n"
  229.  "<HEAD>\n"
  230.  "<TITLE>WWWOFFLE - Interactive Monitor Form Error</TITLE>\n"
  231.  "</HEAD>\n"
  232.  "<BODY>\n"
  233.  "<H1 align=center>WWWOFFLE Interactive Monitor Form Error</H1>\n"
  234.  "<p align=center>\n";
  235.  char *middle1=
  236.  "The reply from the form that your browser sent did not have a body.\n";
  237.  char *middle2=
  238.  "The reply from the form that your browser sent\n"
  239.  "<br><b><tt>\n";
  240.  char *middle3=
  241.  "\n"
  242.  "</tt></b><br>\n"
  243.  "had an error and could not be parsed.\n";
  244.  char *tail=
  245.  "<p align=center>[<a href=\"/refresh/\">Back to the Monitor page</a>]</p>"
  246.  "</BODY>\n"
  247.  "</HTML>\n";
  248.  
  249.  write_string(fd,head);
  250.  if(!body)
  251.     write_string(fd,middle1);
  252.  else
  253.    {
  254.     write_string(fd,middle2);
  255.     write_string(fd,body);
  256.     write_string(fd,middle3);
  257.    }
  258.  write_string(fd,tail);
  259. }
  260.  
  261.  
  262. /*++++++++++++++++++++++++++++++++++++++
  263.   Inform the user that the specified monitor page is illegal.
  264.  
  265.   int fd The file descriptor to write to.
  266.  
  267.   char *path The specified path.
  268.  
  269.   char *args The arguments to the page.
  270.   ++++++++++++++++++++++++++++++++++++++*/
  271.  
  272. static void IllegalMonitorPage(int fd,char *path,char *args)
  273. {
  274.  char *head=
  275.  "HTTP/1.0 404 WWWOFFLE Illegal Monitor Page\r\n"
  276.  "Content-type: text/html\r\n"
  277.  "\r\n"
  278.  "<HTML>\n"
  279.  "<HEAD>\n"
  280.  "<TITLE>WWWOFFLE - Illegal Interactive Monitor Page</TITLE>\n"
  281.  "</HEAD>\n"
  282.  "<BODY>\n"
  283.  "<H1 align=center>WWWOFFLE Illegal Interactive Monitor Page</H1>\n"
  284.  "<p align=center>\n"
  285.  "Your request for the monitor URL\n"
  286.  "<br><b><tt>\n";
  287.  char *tail=
  288.  "\n"
  289.  "</tt></b><br>\n"
  290.  "is illegal, select the link below for the main interactive monitor page.\n"
  291.  "<br>\n"
  292.  "<a href=\"/monitor/\">/monitor/</a>\n"
  293.  "</BODY>\n"
  294.  "</HTML>\n";
  295.  
  296.  write_string(fd,head);
  297.  if(args)
  298.     write_formatted(fd,"/%s?%s",path,args);
  299.  else
  300.     write_formatted(fd,"/%s",path);
  301.  write_string(fd,tail);
  302. }
  303.  
  304.  
  305. /*++++++++++++++++++++++++++++++++++++++
  306.   Convert monitor requests into outgoing requests.
  307.   ++++++++++++++++++++++++++++++++++++++*/
  308.  
  309. void RequestMonitoredPages(void)
  310. {
  311.  DIR *dir;
  312.  struct dirent* ent;
  313.  int now=time(NULL);
  314.  
  315.  /* Open the monitor subdirectory. */
  316.  
  317.  if(chdir("monitor"))
  318.    {PrintMessage(Warning,"Cannot change to directory 'monitor' [%!s]; no files monitored.");return;}
  319.  
  320.  dir=opendir(".");
  321.  if(!dir)
  322.    {PrintMessage(Warning,"Cannot open directory 'monitor' [%!s]; no files monitored.");chdir("..");return;}
  323.  
  324.  ent=readdir(dir);  /* skip .  */
  325.  if(!ent)
  326.    {PrintMessage(Warning,"Cannot read directory 'monitor' [%!s]; no files monitored.");closedir(dir);chdir("..");return;}
  327.  ent=readdir(dir);  /* skip .. */
  328.  
  329.  /* Scan through all of the files. */
  330.  
  331.  while((ent=readdir(dir)))
  332.    {
  333.     struct stat buf;
  334.  
  335.     if(lstat(ent->d_name,&buf))
  336.       {PrintMessage(Inform,"Cannot stat file '%s' [%!s]; race condition?",ent->d_name);return;}
  337.     else if(S_ISREG(buf.st_mode) && *ent->d_name=='O')
  338.       {
  339.        int atimedays=(now-buf.st_atime+3600)/(24*3600);
  340.        int mtimedays=(now-buf.st_mtime+3600)/(24*3600);
  341.  
  342.        PrintMessage(Debug,"Monitoring %s; atimedays=%d mtimedays=%d =>%s",ent->d_name,atimedays,mtimedays,
  343.                     (MonitorInterval<=0 ||
  344.                      atimedays>=MonitorInterval ||
  345.                      (atimedays && mtimedays && (mtimedays%MonitorInterval)==0))?"Yes":"No");
  346.  
  347.        if(MonitorInterval<=0 ||
  348.           atimedays>=MonitorInterval ||
  349.           (atimedays && mtimedays && (mtimedays%MonitorInterval)==0))
  350.          {
  351.           char *url=FileNameToURL(ent->d_name);
  352.           int ifd=open(ent->d_name,O_RDONLY);
  353.           init_buffer(ifd);
  354.  
  355.           if(ifd==-1)
  356.              PrintMessage(Warning,"Cannot open monitored file 'monitor/%s' to read [%!s].",ent->d_name);
  357.           else
  358.             {
  359.              int ofd;
  360.  
  361.              chdir("..");
  362.  
  363.              ofd=OpenOutgoingSpoolFile(0);
  364.  
  365.              if(ofd==-1)
  366.                 PrintMessage(Warning,"Cannot open outgoing spool file for monitored URL '%s' [%!s].",url);
  367.              else
  368.                {
  369.                 char *contents=(char*)malloc(buf.st_size);
  370.                 URL *Url=SplitURL(url);
  371.  
  372.                 read_data(ifd,contents,buf.st_size);
  373.                 write_data(ofd,contents,buf.st_size);
  374.  
  375.                 CloseOutgoingSpoolFile(ofd,Url);
  376.  
  377.                 free(contents);
  378.                 FreeURL(Url);
  379.                }
  380.  
  381.              close(ifd);
  382.  
  383.              if(chdir("monitor"))
  384.                {PrintMessage(Warning,"Cannot change back to directory 'monitor' [%!s]; no more files monitored.");closedir(dir);return;}
  385.             }
  386.  
  387.           free(url);
  388.          }
  389.       }
  390.    }
  391.  
  392.  closedir(dir);
  393.  
  394.  chdir("..");
  395. }
  396.