control.c
上传用户:seven77cht
上传日期:2007-01-04
资源大小:486k
文件大小:13k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /***************************************
  2.   $Header: /home/amb/wwwoffle/RCS/control.c 2.38 1999/10/15 09:08:22 amb Exp $
  3.   WWWOFFLE - World Wide Web Offline Explorer - Version 2.5b.
  4.   The HTML interactive control pages.
  5.   ******************/ /******************
  6.   Written by Andrew M. Bishop
  7.   This file Copyright 1997,98,99 Andrew M. Bishop
  8.   It may be distributed under the GNU Public License, version 2, or
  9.   any higher version.  See section COPYING of the GNU Public license
  10.   for conditions under which this file may be redistributed.
  11.   ***************************************/
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <unistd.h>
  16. #include "wwwoffle.h"
  17. #include "misc.h"
  18. #include "config.h"
  19. #include "sockets.h"
  20. #include "errors.h"
  21. /*+ The action to perform. +*/
  22. typedef enum _Action
  23. {
  24.  None,                          /*+ Undecided. +*/
  25.  Online,                        /*+ Tell the server that we are online. +*/
  26.  Autodial,                      /*+ Tell the server that we are in autodial mode. +*/
  27.  Offline,                       /*+ Tell the server that we are offline. +*/
  28.  Fetch,                         /*+ Tell the server to fetch the requested pages. +*/
  29.  Config,                        /*+ Tell the server to re-read the configuration file. +*/
  30.  Purge,                         /*+ Tell the server to purge pages. +*/
  31.  Delete,                        /*+ Delete a page from the cache or a request from the outgoing directory. +*/
  32.  DeleteMultiple,                /*+ Delete mulitple pages from the cache or requests from the outgoing directory. +*/
  33.  ConfigEdit,                    /*+ Edit the config file. +*/
  34. }
  35. Action;
  36. static void ActionControlPage(int fd,Action action,char *command);
  37. static void DeleteControlPage(int fd,char *mode,char *args);
  38. static void DeleteMultipleControlPages(int fd,char *mode,Body *request_body);
  39. static void ControlAuthFail(int fd,char *url);
  40. /*++++++++++++++++++++++++++++++++++++++
  41.   Send to the client one of the pages to control WWWOFFLE using HTML.
  42.   int fd The file descriptor of the client.
  43.   URL *Url The Url that was requested.
  44.   Header *request_head The head of the HTTP request.
  45.   Body *request_body The body of the HTTP request.
  46.   ++++++++++++++++++++++++++++++++++++++*/
  47. void ControlPage(int fd,URL *Url,Header *request_head,Body *request_body)
  48. {
  49.  Action action=None;
  50.  char *newpath=(char*)malloc(strlen(Url->path)-8);
  51.  char *command="";
  52.  strcpy(newpath,Url->path+9);        /* remove the '/control/' */
  53.  if(*newpath && newpath[strlen(newpath)-1]=='/')
  54.     newpath[strlen(newpath)-1]=0;
  55.  /* Determine the action. */
  56.  if(!strcmp(newpath,"online"))
  57.    {action=Online;command="-online";}
  58.  else if(!strcmp(newpath,"autodial"))
  59.    {action=Autodial;command="-autodial";}
  60.  else if(!strcmp(newpath,"offline"))
  61.    {action=Offline;command="-offline";}
  62.  else if(!strcmp(newpath,"fetch"))
  63.    {action=Fetch;command="-fetch";}
  64.  else if(!strcmp(newpath,"config"))
  65.    {action=Config;command="-config";}
  66.  else if(!strcmp(newpath,"purge"))
  67.    {action=Purge;command="-purge";}
  68.  else if(!strncmp(newpath,"delete-multiple",15))
  69.     action=DeleteMultiple;
  70.  else if(!strncmp(newpath,"delete",6))
  71.     action=Delete;
  72.  else if(!strcmp(newpath,"edit"))
  73.     action=ConfigEdit;
  74.  /* Check the authorisation. */
  75.  if(PassWord)
  76.    {
  77.     if(!Url->pass && (action==Delete || action==DeleteMultiple) && Url->args && strstr(newpath,"password="))
  78.       {
  79.        URL *reqUrl=SplitURL(Url->args);
  80.        char *hash=HashOutgoingSpoolFile(reqUrl);
  81.        char *pswd=strstr(newpath,"password=")+9;
  82.        FreeURL(reqUrl);
  83.        if(!hash || strcmp(pswd,hash))
  84.          {
  85.           PrintMessage(Important,"Interactive control webpage delete with password failed.");
  86.           ControlAuthFail(fd,Url->pathp);
  87.           return;
  88.          }
  89.       }
  90.     else if(!Url->pass)
  91.       {
  92.        ControlAuthFail(fd,Url->pathp);
  93.        return;
  94.       }
  95.     else
  96.       {
  97.        if(strcmp(Url->pass,PassWord))
  98.          {
  99.           PrintMessage(Important,"Interactive control webpage authorisation failed.");
  100.           ControlAuthFail(fd,Url->pathp);
  101.           return;
  102.          }
  103.       }
  104.    }
  105.  /* Perform the action. */
  106.  if(action==None && Url->path[9])
  107.    {
  108.     HTMLMessage(fd,404,"WWWOFFLE Illegal Control Page",NULL,"ControlIllegal",
  109.                 "url",Url->pathp,
  110.                 NULL);
  111.     return;
  112.    }
  113.  if(action==None)
  114.     HTMLMessage(fd,200,"WWWOFFLE Control Page",NULL,"ControlPage",
  115.                 NULL);
  116.  else if(action==Delete)
  117.     DeleteControlPage(fd,newpath,Url->args);
  118.  else if(action==DeleteMultiple)
  119.     DeleteMultipleControlPages(fd,newpath,request_body);
  120.  else if(action==ConfigEdit)
  121.     ConfigEditPage(fd,Url->args,request_body);
  122.  else
  123.     ActionControlPage(fd,action,command);
  124.  free(newpath);
  125. }
  126. /*++++++++++++++++++++++++++++++++++++++
  127.   The control page that performs an action.
  128.   int fd The file descriptor to write to.
  129.   Action action The action to perform.
  130.   char *command The command line argument that would be used with wwwoffle.
  131.   ++++++++++++++++++++++++++++++++++++++*/
  132. static void ActionControlPage(int fd,Action action,char *command)
  133. {
  134.  int socket=OpenClientSocket("localhost",WWWOFFLE_Port,ConnectTimeout);
  135.  init_buffer(socket);
  136.  if(socket==-1)
  137.    {
  138.     PrintMessage(Warning,"Cannot open connection to wwwoffle server localhost port %d.",WWWOFFLE_Port);
  139.     HTMLMessage(fd,500,"WWWOFFLE Server Error",NULL,"ServerError",
  140.                 "error","Cannot open connection to wwwoffle server on localhost",
  141.                 NULL);
  142.    }
  143.  else
  144.    {
  145.     char *buffer=NULL;
  146.     HTMLMessage(fd,200,"WWWOFFLE Control Page",NULL,"ControlWWWOFFLE-Head",
  147.                 "command",command,
  148.                 NULL);
  149.     /* Send the message. */
  150.     if(PassWord)
  151.        write_formatted(socket,"WWWOFFLE PASSWORD %srn",PassWord);
  152.     if(action==Online)
  153.        write_string(socket,"WWWOFFLE ONLINErn");
  154.     else if(action==Autodial)
  155.        write_string(socket,"WWWOFFLE AUTODIALrn");
  156.     else if(action==Offline)
  157.        write_string(socket,"WWWOFFLE OFFLINErn");
  158.     else if(action==Fetch)
  159.        write_string(socket,"WWWOFFLE FETCHrn");
  160.     else if(action==Config)
  161.        write_string(socket,"WWWOFFLE CONFIGrn");
  162.     else if(action==Purge)
  163.        write_string(socket,"WWWOFFLE PURGErn");
  164.     while((buffer=read_line(socket,buffer)))
  165.        write_string(fd,buffer);
  166.     HTMLMessageBody(fd,"ControlWWWOFFLE-Tail",
  167.                     NULL);
  168.    }
  169. }
  170. /*++++++++++++++++++++++++++++++++++++++
  171.   The control page that deletes a cached page or a request.
  172.   int fd The file descriptor to write to.
  173.   char *mode The mode of deletion that was requested.
  174.   char *args The arguments specified.
  175.   ++++++++++++++++++++++++++++++++++++++*/
  176. static void DeleteControlPage(int fd,char *path,char *args)
  177. {
  178.  char *pling=NULL;
  179.  char *url=NULL,*req=NULL,*mon=NULL;
  180.  int all=0;
  181.  if(args && *args=='!')
  182.    {
  183.     args++;
  184.     pling=strchr(args,'!');
  185.     if(pling)
  186.        *pling=0;
  187.    }
  188.  /* Decide what sort of deletion is required. */
  189.  if(strlen(path)>=10 && !strncmp(path+10,"-all",4))
  190.     all=1;
  191.  if(!strncmp(path,"delete-url",10))
  192.     url=args;
  193.  else if(!strncmp(path,"delete-mon",10))
  194.    {
  195.     mon=args;
  196.     if(all)
  197.        mon="all";
  198.    }
  199.  else if(!strncmp(path,"delete-req",10))
  200.    {
  201.     req=args;
  202.     if(all)
  203.        req="all";
  204.    }
  205.  /* Do the required deletion. */
  206.  if(!url && !mon && !req)
  207.    {
  208.     char *controlurl=(char*)malloc(strlen(path)+strlen(args)+24);
  209.     sprintf(controlurl,"/control/%s?%s",path,args);
  210.     PrintMessage(Important,"Invalid interactive delete page requested; path='%s' args='%s'.",path,args);
  211.     HTMLMessage(fd,404,"WWWOFFLE Illegal Control Page",NULL,"ControlIllegal",
  212.                 "url",controlurl,
  213.                 NULL);
  214.     free(controlurl);
  215.    }
  216.  else
  217.    {
  218.     char *err;
  219.     HTMLMessageHead(fd,200,"WWWOFFLE Delete Control Page",
  220.                     NULL);
  221.     HTMLMessageBody(fd,"ControlDelete-Head",
  222.                     "req",req,
  223.                     "mon",mon,
  224.                     "url",url,
  225.                     NULL);
  226.     if(req)
  227.       {
  228.        if(all)
  229.           err=DeleteOutgoingSpoolFile(NULL);
  230.        else
  231.          {
  232.           URL *reqUrl=SplitURL(req);
  233.           if(reqUrl->Protocol)
  234.              err=DeleteOutgoingSpoolFile(reqUrl);
  235.           else
  236.              err="Illegal Protocol";
  237.           FreeURL(reqUrl);
  238.          }
  239.        HTMLMessageBody(fd,"ControlDelete-Body",
  240.                        "page",all?"":req,
  241.                        "all",all?"yes":"",
  242.                        "error",err,
  243.                        NULL);
  244.       }
  245.     else if(mon)
  246.       {
  247.        if(all)
  248.           err=DeleteMonitorSpoolFile(NULL);
  249.        else
  250.          {
  251.           URL *monUrl=SplitURL(mon);
  252.           if(monUrl->Protocol)
  253.              err=DeleteMonitorSpoolFile(monUrl);
  254.           else
  255.              err="Illegal Protocol";
  256.           FreeURL(monUrl);
  257.          }
  258.        HTMLMessageBody(fd,"ControlDelete-Body",
  259.                        "page",all?"":mon,
  260.                        "all",all?"yes":"",
  261.                        "error",err,
  262.                        NULL);
  263.       }
  264.     else if(url)
  265.       {
  266.        URL *urlUrl=SplitURL(url);
  267.        if(urlUrl->Protocol)
  268.           err=DeleteWebpageSpoolFile(urlUrl,!!all);
  269.        else
  270.           err="Illegal Protocol";
  271.        HTMLMessageBody(fd,"ControlDelete-Body",
  272.                        "page",url,
  273.                        "all",all?"yes":"",
  274.                        "error",err,
  275.                        NULL);
  276.        FreeURL(urlUrl);
  277.       }
  278.     HTMLMessageBody(fd,"ControlDelete-Tail",
  279.                     "req",req,
  280.                     "mon",mon,
  281.                     "url",url,
  282.                     NULL);
  283.    }
  284.  if(pling)
  285.     *pling='!';
  286. }
  287. /*++++++++++++++++++++++++++++++++++++++
  288.   The control page that deletes multiple cached pages or requests.
  289.   int fd The file descriptor to write to.
  290.   char *mode The mode of deletion that was requested.
  291.   Body *request_body The body of the delete command.
  292.   ++++++++++++++++++++++++++++++++++++++*/
  293. static void DeleteMultipleControlPages(int fd,char *path,Body *request_body)
  294. {
  295.  char *url=NULL,*req=NULL,*mon=NULL;
  296.  /* Decide what sort of deletion is required. */
  297.  if(!strncmp(path,"delete-multiple-url",19))
  298.     url="yes";
  299.  else if(!strncmp(path,"delete-multiple-mon",19))
  300.     mon="yes";
  301.  else if(!strncmp(path,"delete-multiple-req",19))
  302.     req="yes";
  303.  /* Do the required deletion. */
  304.  if(!request_body || (!url && !mon && !req))
  305.    {
  306.     char *controlurl=(char*)malloc(strlen(path)+24);
  307.     sprintf(controlurl,"/control/%s",path);
  308.     PrintMessage(Important,"Invalid interactive delete page requested; path='%s'.",path);
  309.     HTMLMessage(fd,404,"WWWOFFLE Illegal Control Page",NULL,"ControlIllegal",
  310.                 "url",controlurl,
  311.                 NULL);
  312.     free(controlurl);
  313.    }
  314.  else
  315.    {
  316.     char *err;
  317.     char *p=request_body->content;
  318.     HTMLMessageHead(fd,200,"WWWOFFLE Multiple Delete Control Page",
  319.                     NULL);
  320.     HTMLMessageBody(fd,"ControlDelete-Head",
  321.                     "req",req,
  322.                     "mon",mon,
  323.                     "url",url,
  324.                     NULL);
  325.     while(*p)
  326.       {
  327.        char *body=p,*page,*equal=NULL;
  328.        while(*p && *p!='&')
  329.          {
  330.           if(*p=='=')
  331.              equal=p;
  332.           p++;
  333.          }
  334.        *p=0;p++;
  335.        if(!equal || strcmp(equal,"=Y"))
  336.           continue;
  337.        *equal=0;
  338.        page=URLDecode(body,1);
  339.        if(req)
  340.          {
  341.           URL *reqUrl=SplitURL(page);
  342.           if(reqUrl->Protocol)
  343.              err=DeleteOutgoingSpoolFile(reqUrl);
  344.           else
  345.              err="Illegal Protocol";
  346.           HTMLMessageBody(fd,"ControlDelete-Body",
  347.                           "page",page,
  348.                           "all",NULL,
  349.                           "error",err,
  350.                           NULL);
  351.           FreeURL(reqUrl);
  352.          }
  353.        else if(mon)
  354.          {
  355.           URL *monUrl=SplitURL(page);
  356.           if(monUrl->Protocol)
  357.              err=DeleteMonitorSpoolFile(monUrl);
  358.           else
  359.              err="Illegal Protocol";
  360.           HTMLMessageBody(fd,"ControlDelete-Body",
  361.                           "page",page,
  362.                           "all",NULL,
  363.                           "error",err,
  364.                           NULL);
  365.           FreeURL(monUrl);
  366.          }
  367.        else if(url)
  368.          {
  369.           URL *urlUrl=SplitURL(page);
  370.           if(urlUrl->Protocol)
  371.              err=DeleteWebpageSpoolFile(urlUrl,0);
  372.           else
  373.              err="Illegal Protocol";
  374.           HTMLMessageBody(fd,"ControlDelete-Body",
  375.                           "page",page,
  376.                           "all",NULL,
  377.                           "error",err,
  378.                           NULL);
  379.           FreeURL(urlUrl);
  380.          }
  381.        free(page);
  382.       }
  383.     HTMLMessageBody(fd,"ControlDelete-Tail",
  384.                     "req",req,
  385.                     "mon",mon,
  386.                     "url",url,
  387.                     NULL);
  388.    }
  389. }
  390. /*++++++++++++++++++++++++++++++++++++++
  391.   Inform the user that the authorisation failed.
  392.   int fd The file descriptor to write to.
  393.   char *url The specified path.
  394.   ++++++++++++++++++++++++++++++++++++++*/
  395. static void ControlAuthFail(int fd,char *url)
  396. {
  397.  HTMLMessageHead(fd,401,"WWWOFFLE Authorisation Failed",
  398.                  "WWW-Authenticate","Basic realm="control"",
  399.                  NULL);
  400.  HTMLMessageBody(fd,"ControlAuthFail",
  401.                  "url",url,
  402.                  NULL);
  403. }