control.c
上传用户:seven77cht
上传日期:2007-01-04
资源大小:486k
文件大小:13k
- /***************************************
- $Header: /home/amb/wwwoffle/RCS/control.c 2.38 1999/10/15 09:08:22 amb Exp $
- WWWOFFLE - World Wide Web Offline Explorer - Version 2.5b.
- The HTML interactive control pages.
- ******************/ /******************
- Written by Andrew M. Bishop
- This file Copyright 1997,98,99 Andrew M. Bishop
- It may be distributed under the GNU Public License, version 2, or
- any higher version. See section COPYING of the GNU Public license
- for conditions under which this file may be redistributed.
- ***************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include "wwwoffle.h"
- #include "misc.h"
- #include "config.h"
- #include "sockets.h"
- #include "errors.h"
- /*+ The action to perform. +*/
- typedef enum _Action
- {
- None, /*+ Undecided. +*/
- Online, /*+ Tell the server that we are online. +*/
- Autodial, /*+ Tell the server that we are in autodial mode. +*/
- Offline, /*+ Tell the server that we are offline. +*/
- Fetch, /*+ Tell the server to fetch the requested pages. +*/
- Config, /*+ Tell the server to re-read the configuration file. +*/
- Purge, /*+ Tell the server to purge pages. +*/
- Delete, /*+ Delete a page from the cache or a request from the outgoing directory. +*/
- DeleteMultiple, /*+ Delete mulitple pages from the cache or requests from the outgoing directory. +*/
- ConfigEdit, /*+ Edit the config file. +*/
- }
- Action;
- static void ActionControlPage(int fd,Action action,char *command);
- static void DeleteControlPage(int fd,char *mode,char *args);
- static void DeleteMultipleControlPages(int fd,char *mode,Body *request_body);
- static void ControlAuthFail(int fd,char *url);
- /*++++++++++++++++++++++++++++++++++++++
- Send to the client one of the pages to control WWWOFFLE using HTML.
- int fd The file descriptor of the client.
- URL *Url The Url that was requested.
- Header *request_head The head of the HTTP request.
- Body *request_body The body of the HTTP request.
- ++++++++++++++++++++++++++++++++++++++*/
- void ControlPage(int fd,URL *Url,Header *request_head,Body *request_body)
- {
- Action action=None;
- char *newpath=(char*)malloc(strlen(Url->path)-8);
- char *command="";
- strcpy(newpath,Url->path+9); /* remove the '/control/' */
- if(*newpath && newpath[strlen(newpath)-1]=='/')
- newpath[strlen(newpath)-1]=0;
- /* Determine the action. */
- if(!strcmp(newpath,"online"))
- {action=Online;command="-online";}
- else if(!strcmp(newpath,"autodial"))
- {action=Autodial;command="-autodial";}
- else if(!strcmp(newpath,"offline"))
- {action=Offline;command="-offline";}
- else if(!strcmp(newpath,"fetch"))
- {action=Fetch;command="-fetch";}
- else if(!strcmp(newpath,"config"))
- {action=Config;command="-config";}
- else if(!strcmp(newpath,"purge"))
- {action=Purge;command="-purge";}
- else if(!strncmp(newpath,"delete-multiple",15))
- action=DeleteMultiple;
- else if(!strncmp(newpath,"delete",6))
- action=Delete;
- else if(!strcmp(newpath,"edit"))
- action=ConfigEdit;
- /* Check the authorisation. */
- if(PassWord)
- {
- if(!Url->pass && (action==Delete || action==DeleteMultiple) && Url->args && strstr(newpath,"password="))
- {
- URL *reqUrl=SplitURL(Url->args);
- char *hash=HashOutgoingSpoolFile(reqUrl);
- char *pswd=strstr(newpath,"password=")+9;
- FreeURL(reqUrl);
- if(!hash || strcmp(pswd,hash))
- {
- PrintMessage(Important,"Interactive control webpage delete with password failed.");
- ControlAuthFail(fd,Url->pathp);
- return;
- }
- }
- else if(!Url->pass)
- {
- ControlAuthFail(fd,Url->pathp);
- return;
- }
- else
- {
- if(strcmp(Url->pass,PassWord))
- {
- PrintMessage(Important,"Interactive control webpage authorisation failed.");
- ControlAuthFail(fd,Url->pathp);
- return;
- }
- }
- }
- /* Perform the action. */
- if(action==None && Url->path[9])
- {
- HTMLMessage(fd,404,"WWWOFFLE Illegal Control Page",NULL,"ControlIllegal",
- "url",Url->pathp,
- NULL);
- return;
- }
- if(action==None)
- HTMLMessage(fd,200,"WWWOFFLE Control Page",NULL,"ControlPage",
- NULL);
- else if(action==Delete)
- DeleteControlPage(fd,newpath,Url->args);
- else if(action==DeleteMultiple)
- DeleteMultipleControlPages(fd,newpath,request_body);
- else if(action==ConfigEdit)
- ConfigEditPage(fd,Url->args,request_body);
- else
- ActionControlPage(fd,action,command);
- free(newpath);
- }
- /*++++++++++++++++++++++++++++++++++++++
- The control page that performs an action.
- int fd The file descriptor to write to.
- Action action The action to perform.
- char *command The command line argument that would be used with wwwoffle.
- ++++++++++++++++++++++++++++++++++++++*/
- static void ActionControlPage(int fd,Action action,char *command)
- {
- int socket=OpenClientSocket("localhost",WWWOFFLE_Port,ConnectTimeout);
- init_buffer(socket);
- if(socket==-1)
- {
- PrintMessage(Warning,"Cannot open connection to wwwoffle server localhost port %d.",WWWOFFLE_Port);
- HTMLMessage(fd,500,"WWWOFFLE Server Error",NULL,"ServerError",
- "error","Cannot open connection to wwwoffle server on localhost",
- NULL);
- }
- else
- {
- char *buffer=NULL;
- HTMLMessage(fd,200,"WWWOFFLE Control Page",NULL,"ControlWWWOFFLE-Head",
- "command",command,
- NULL);
- /* Send the message. */
- if(PassWord)
- write_formatted(socket,"WWWOFFLE PASSWORD %srn",PassWord);
- if(action==Online)
- write_string(socket,"WWWOFFLE ONLINErn");
- else if(action==Autodial)
- write_string(socket,"WWWOFFLE AUTODIALrn");
- else if(action==Offline)
- write_string(socket,"WWWOFFLE OFFLINErn");
- else if(action==Fetch)
- write_string(socket,"WWWOFFLE FETCHrn");
- else if(action==Config)
- write_string(socket,"WWWOFFLE CONFIGrn");
- else if(action==Purge)
- write_string(socket,"WWWOFFLE PURGErn");
- while((buffer=read_line(socket,buffer)))
- write_string(fd,buffer);
- HTMLMessageBody(fd,"ControlWWWOFFLE-Tail",
- NULL);
- }
- }
- /*++++++++++++++++++++++++++++++++++++++
- The control page that deletes a cached page or a request.
- int fd The file descriptor to write to.
- char *mode The mode of deletion that was requested.
- char *args The arguments specified.
- ++++++++++++++++++++++++++++++++++++++*/
- static void DeleteControlPage(int fd,char *path,char *args)
- {
- char *pling=NULL;
- char *url=NULL,*req=NULL,*mon=NULL;
- int all=0;
- if(args && *args=='!')
- {
- args++;
- pling=strchr(args,'!');
- if(pling)
- *pling=0;
- }
- /* Decide what sort of deletion is required. */
- if(strlen(path)>=10 && !strncmp(path+10,"-all",4))
- all=1;
- if(!strncmp(path,"delete-url",10))
- url=args;
- else if(!strncmp(path,"delete-mon",10))
- {
- mon=args;
- if(all)
- mon="all";
- }
- else if(!strncmp(path,"delete-req",10))
- {
- req=args;
- if(all)
- req="all";
- }
- /* Do the required deletion. */
- if(!url && !mon && !req)
- {
- char *controlurl=(char*)malloc(strlen(path)+strlen(args)+24);
- sprintf(controlurl,"/control/%s?%s",path,args);
- PrintMessage(Important,"Invalid interactive delete page requested; path='%s' args='%s'.",path,args);
- HTMLMessage(fd,404,"WWWOFFLE Illegal Control Page",NULL,"ControlIllegal",
- "url",controlurl,
- NULL);
- free(controlurl);
- }
- else
- {
- char *err;
- HTMLMessageHead(fd,200,"WWWOFFLE Delete Control Page",
- NULL);
- HTMLMessageBody(fd,"ControlDelete-Head",
- "req",req,
- "mon",mon,
- "url",url,
- NULL);
- if(req)
- {
- if(all)
- err=DeleteOutgoingSpoolFile(NULL);
- else
- {
- URL *reqUrl=SplitURL(req);
- if(reqUrl->Protocol)
- err=DeleteOutgoingSpoolFile(reqUrl);
- else
- err="Illegal Protocol";
- FreeURL(reqUrl);
- }
- HTMLMessageBody(fd,"ControlDelete-Body",
- "page",all?"":req,
- "all",all?"yes":"",
- "error",err,
- NULL);
- }
- else if(mon)
- {
- if(all)
- err=DeleteMonitorSpoolFile(NULL);
- else
- {
- URL *monUrl=SplitURL(mon);
- if(monUrl->Protocol)
- err=DeleteMonitorSpoolFile(monUrl);
- else
- err="Illegal Protocol";
- FreeURL(monUrl);
- }
- HTMLMessageBody(fd,"ControlDelete-Body",
- "page",all?"":mon,
- "all",all?"yes":"",
- "error",err,
- NULL);
- }
- else if(url)
- {
- URL *urlUrl=SplitURL(url);
- if(urlUrl->Protocol)
- err=DeleteWebpageSpoolFile(urlUrl,!!all);
- else
- err="Illegal Protocol";
- HTMLMessageBody(fd,"ControlDelete-Body",
- "page",url,
- "all",all?"yes":"",
- "error",err,
- NULL);
- FreeURL(urlUrl);
- }
- HTMLMessageBody(fd,"ControlDelete-Tail",
- "req",req,
- "mon",mon,
- "url",url,
- NULL);
- }
- if(pling)
- *pling='!';
- }
- /*++++++++++++++++++++++++++++++++++++++
- The control page that deletes multiple cached pages or requests.
- int fd The file descriptor to write to.
- char *mode The mode of deletion that was requested.
- Body *request_body The body of the delete command.
- ++++++++++++++++++++++++++++++++++++++*/
- static void DeleteMultipleControlPages(int fd,char *path,Body *request_body)
- {
- char *url=NULL,*req=NULL,*mon=NULL;
- /* Decide what sort of deletion is required. */
- if(!strncmp(path,"delete-multiple-url",19))
- url="yes";
- else if(!strncmp(path,"delete-multiple-mon",19))
- mon="yes";
- else if(!strncmp(path,"delete-multiple-req",19))
- req="yes";
- /* Do the required deletion. */
- if(!request_body || (!url && !mon && !req))
- {
- char *controlurl=(char*)malloc(strlen(path)+24);
- sprintf(controlurl,"/control/%s",path);
- PrintMessage(Important,"Invalid interactive delete page requested; path='%s'.",path);
- HTMLMessage(fd,404,"WWWOFFLE Illegal Control Page",NULL,"ControlIllegal",
- "url",controlurl,
- NULL);
- free(controlurl);
- }
- else
- {
- char *err;
- char *p=request_body->content;
- HTMLMessageHead(fd,200,"WWWOFFLE Multiple Delete Control Page",
- NULL);
- HTMLMessageBody(fd,"ControlDelete-Head",
- "req",req,
- "mon",mon,
- "url",url,
- NULL);
- while(*p)
- {
- char *body=p,*page,*equal=NULL;
- while(*p && *p!='&')
- {
- if(*p=='=')
- equal=p;
- p++;
- }
- *p=0;p++;
- if(!equal || strcmp(equal,"=Y"))
- continue;
- *equal=0;
- page=URLDecode(body,1);
- if(req)
- {
- URL *reqUrl=SplitURL(page);
- if(reqUrl->Protocol)
- err=DeleteOutgoingSpoolFile(reqUrl);
- else
- err="Illegal Protocol";
- HTMLMessageBody(fd,"ControlDelete-Body",
- "page",page,
- "all",NULL,
- "error",err,
- NULL);
- FreeURL(reqUrl);
- }
- else if(mon)
- {
- URL *monUrl=SplitURL(page);
- if(monUrl->Protocol)
- err=DeleteMonitorSpoolFile(monUrl);
- else
- err="Illegal Protocol";
- HTMLMessageBody(fd,"ControlDelete-Body",
- "page",page,
- "all",NULL,
- "error",err,
- NULL);
- FreeURL(monUrl);
- }
- else if(url)
- {
- URL *urlUrl=SplitURL(page);
- if(urlUrl->Protocol)
- err=DeleteWebpageSpoolFile(urlUrl,0);
- else
- err="Illegal Protocol";
- HTMLMessageBody(fd,"ControlDelete-Body",
- "page",page,
- "all",NULL,
- "error",err,
- NULL);
- FreeURL(urlUrl);
- }
- free(page);
- }
- HTMLMessageBody(fd,"ControlDelete-Tail",
- "req",req,
- "mon",mon,
- "url",url,
- NULL);
- }
- }
- /*++++++++++++++++++++++++++++++++++++++
- Inform the user that the authorisation failed.
- int fd The file descriptor to write to.
- char *url The specified path.
- ++++++++++++++++++++++++++++++++++++++*/
- static void ControlAuthFail(int fd,char *url)
- {
- HTMLMessageHead(fd,401,"WWWOFFLE Authorisation Failed",
- "WWW-Authenticate","Basic realm="control"",
- NULL);
- HTMLMessageBody(fd,"ControlAuthFail",
- "url",url,
- NULL);
- }