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

  1. /***************************************
  2.   $Header: /home/amb/wwwoffle/RCS/control.c 2.21 1998/03/02 15:05:58 amb Exp $
  3.  
  4.   WWWOFFLE - World Wide Web Offline Explorer - Version 2.1.
  5.   The HTML interactive control pages.
  6.   ******************/ /******************
  7.   Written by Andrew M. Bishop
  8.  
  9.   This file Copyright 1997,98 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.  
  22. #include "wwwoffle.h"
  23. #include "misc.h"
  24. #include "config.h"
  25. #include "sockets.h"
  26. #include "errors.h"
  27.  
  28.  
  29. /*+ The action to perform. +*/
  30. typedef enum _Action
  31. {
  32.  None,                          /*+ Undecided. +*/
  33.  Online,                        /*+ Tell the server that we are online. +*/
  34.  Autodial,                      /*+ Tell the server that we are in autodial mode. +*/
  35.  Offline,                       /*+ Tell the server that we are offline. +*/
  36.  Fetch,                         /*+ Tell the server to fetch the requested pages. +*/
  37.  Config,                        /*+ Tell the server to re-read the configuration file. +*/
  38.  Purge,                         /*+ Tell the server to purge pages. +*/
  39.  Delete,                        /*+ Delete a page from the cache or a request from the outgoing directory. +*/
  40.  ConfigEdit,                    /*+ Edit the config file. +*/
  41. }
  42. Action;
  43.  
  44.  
  45. static void MainControlPage(int fd);
  46. static void ActionControlPage(int fd,Action action,char *command);
  47. static void DeleteControlPage(int fd,char *file);
  48. static void IllegalControlPage(int fd,char *path,char *args);
  49. static void ControlAuthFail(int fd,char *path);
  50. static int MatchPassword(char *try,char *actual);
  51.  
  52.  
  53. /*++++++++++++++++++++++++++++++++++++++
  54.   Send to the client one of the pages to control WWWOFFLE using HTML.
  55.  
  56.   int fd The file descriptor of the client.
  57.  
  58.   char *path The path that was specified.
  59.  
  60.   char *args The arguments that were passed.
  61.  
  62.   char *request_head The head of the HTTP request.
  63.  
  64.   char *request_body The body of the HTTP request.
  65.   ++++++++++++++++++++++++++++++++++++++*/
  66.  
  67. void ControlPage(int fd,char *path,char *args,char *request_head,char *request_body)
  68. {
  69.  Action action=None;
  70.  char *newpath=(char*)malloc(strlen(path)+1);
  71.  char *command="";
  72.  
  73.  strcpy(newpath,path);
  74.  
  75.  if(*newpath && newpath[strlen(newpath)-1]=='/')
  76.     newpath[strlen(newpath)-1]=0;
  77.  
  78.  if(!strcmp(newpath,"online"))
  79.    {action=Online;command="-online";}
  80.  else if(!strcmp(newpath,"autodial"))
  81.    {action=Autodial;command="-autodial";}
  82.  else if(!strcmp(newpath,"offline"))
  83.    {action=Offline;command="-offline";}
  84.  else if(!strcmp(newpath,"fetch"))
  85.    {action=Fetch;command="-fetch";}
  86.  else if(!strcmp(newpath,"config"))
  87.    {action=Config;command="-config";}
  88.  else if(!strcmp(newpath,"purge"))
  89.    {action=Purge;command="-purge";}
  90.  else if(!strcmp(newpath,"delete"))
  91.     action=Delete;
  92.  else if(!strcmp(newpath,"edit"))
  93.     action=ConfigEdit;
  94.  
  95.  if(PassWord)
  96.    {
  97.     char *auth=strstr(request_head,"\nAuthorization:");
  98.  
  99.     if(!auth && (action==Delete && !strncmp(args,"password=",9)))
  100.        ;
  101.     else if(!auth)
  102.       {
  103.        ControlAuthFail(fd,newpath);
  104.        return;
  105.       }
  106.     else
  107.       {
  108.        char *eol,*type,*pswd;
  109.        int n;
  110.  
  111.        auth+=15;
  112.        eol=strchr(auth,'\n');
  113.        type=(char*)malloc(eol-auth);
  114.        pswd=(char*)malloc(eol-auth);
  115.        *eol=0;
  116.        n=sscanf(auth,"%s %s",type,pswd);
  117.        *eol='\n';
  118.  
  119.        if(n!=2 || strcasecmp(type,"Basic") || !MatchPassword(pswd,PassWord))
  120.          {
  121.           ControlAuthFail(fd,newpath);
  122.           PrintMessage(Important,"Interactive control webpage authorisation failed.");
  123.           return;
  124.          }
  125.       }
  126.    }
  127.  
  128.  if(action==None && *newpath)
  129.    {
  130.     IllegalControlPage(fd,newpath,NULL);
  131.     return;
  132.    }
  133.  
  134.  if(action==None)
  135.     MainControlPage(fd);
  136.  else if(action==Delete)
  137.     DeleteControlPage(fd,args);
  138.  else if(action==ConfigEdit)
  139.     ConfigEditPage(fd,args,request_body);
  140.  else
  141.     ActionControlPage(fd,action,command);
  142. }
  143.  
  144.  
  145. /*++++++++++++++++++++++++++++++++++++++
  146.   The main control page with all of the buttons.
  147.  
  148.   int fd The file descriptor to write to.
  149.   ++++++++++++++++++++++++++++++++++++++*/
  150.  
  151. static void MainControlPage(int fd)
  152. {
  153.  char *page=
  154.  "HTTP/1.0 200 WWWOFFLE Control Page\r\n"
  155.  "Content-type: text/html\r\n"
  156.  "\r\n"
  157.  "<HTML>\n"
  158.  "<HEAD>\n"
  159.  "<TITLE>WWWOFFLE - Interactive Control Page</TITLE>\n"
  160.  "</HEAD>\n"
  161.  "<BODY>\n"
  162.  "<H1 align=center>WWWOFFLE Interactive Control Page</H1>\n"
  163.  "The <b>wwwoffled</b> demon program can be controlled from here.\n"
  164.  "<h2>Command Line Replacements</h2>\n"
  165.  "All of the control actions available in the <b>wwwoffle</b> program are here.\n"
  166.  "<p>\n"
  167.  "<form action=\"/control/online\" method=post>\n"
  168.  "<input type=\"hidden\" name=action value=\"online\">\n"
  169.  "<input type=\"submit\" value=\"Online\"> Put the <b>wwwoffled</b> program online.\n"
  170.  "</form>\n"
  171.  "<form action=\"/control/autodial\" method=post>\n"
  172.  "<input type=\"hidden\" name=action value=\"autodial\">\n"
  173.  "<input type=\"submit\" value=\"Autodial\"> Put the <b>wwwoffled</b> program in the autodial mode.\n"
  174.  "</form>\n"
  175.  "<form action=\"/control/offline\" method=post>\n"
  176.  "<input type=\"hidden\" name=action value=\"offline\">\n"
  177.  "<input type=\"submit\" value=\"Offline\"> Put the <b>wwwoffled</b> program offline.\n"
  178.  "</form>\n"
  179.  "<form action=\"/control/fetch\" method=post>\n"
  180.  "<input type=\"hidden\" name=action value=\"fetch\">\n"
  181.  "<input type=\"submit\" value=\"Fetch\"> Fetch the pages that <b>wwwoffled</b> has pending.\n"
  182.  "</form>\n"
  183.  "<form action=\"/control/purge\" method=post>\n"
  184.  "<input type=\"hidden\" name=action value=\"purge\">\n"
  185.  "<input type=\"submit\" value=\"Purge\"> Force the <b>wwwoffled</b> cache to be purged.\n"
  186.  "</form>\n"
  187.  "<h2>Edit The Configuration File</h2>\n"
  188.  "The configuration file (wwwoffle.conf) can be edited on the following page.\n"
  189.  "<p>\n"
  190.  "<a href=\"/control/edit\">Edit the configuration file</a>.\n"
  191.  "<p>\n"
  192.  "<form action=\"/control/config\" method=post>\n"
  193.  "<input type=\"hidden\" name=action value=\"config\">\n"
  194.  "<input type=\"submit\" value=\"Config\"> Force <b>wwwoffled</b> to re-read the configuration file.\n"
  195.  "</form>\n"
  196.  "<h2>Delete Pages or Outgoing Requests</h2>\n"
  197.  "You can also delete a specified cached URL or a request from the outgoing directory.\n"
  198.  "<form action=\"/control/delete\" method=get>\n"
  199.  "<input type=\"submit\" value=\"Delete URL From Cache\">\n"
  200.  "<input type=\"text\" size=40 name=url value=\"\">\n"
  201.  "<br><input type=\"checkbox\" name=\"all\" value=\"yes\"> Delete all files from a particular host\n"
  202.  "</form>\n"
  203.  "<form action=\"/control/delete\" method=get>\n"
  204.  "<input type=\"submit\" value=\"Delete URL From Monitored list\">\n"
  205.  "<input type=\"text\" size=40 name=mon value=\"\">\n"
  206.  "</form>\n"
  207.  "<form action=\"/control/delete\" method=get>\n"
  208.  "<input type=\"submit\" value=\"Delete URL From Outgoing\">\n"
  209.  "<input type=\"text\" size=40 name=req value=\"\">\n"
  210.  "<br><input type=\"checkbox\" name=\"all\" value=\"yes\"> Delete all outgoing files\n"
  211.  "</form>\n"
  212.  "<p align=center>[<a href=\"/\">Back to the Welcome page</a>]</p>\n"
  213.  "</BODY>\n"
  214.  "</HTML>\n";
  215.  
  216.  write_string(fd,page);
  217. }
  218.  
  219.  
  220. /*++++++++++++++++++++++++++++++++++++++
  221.   The control page that performs an action.
  222.  
  223.   int fd The file descriptor to write to.
  224.  
  225.   Action action The action to perform.
  226.  
  227.   char *command The command line argument that would be used with wwwoffle.
  228.   ++++++++++++++++++++++++++++++++++++++*/
  229.  
  230. static void ActionControlPage(int fd,Action action,char *command)
  231. {
  232.  int socket=OpenClientSocket("localhost",WWWOFFLE_Port);
  233.  init_buffer(socket);
  234.  
  235.  if(socket==-1)
  236.    {
  237.     ServerError(fd,"Cannot open connection to wwwoffle server on localhost");
  238.     PrintMessage(Warning,"Cannot open connection to wwwoffle server localhost port %d.",WWWOFFLE_Port);
  239.    }
  240.  else
  241.    {
  242.     char *buffer=NULL;
  243.     char *string=(char*)malloc(32+strlen(command)+strlen(ConfigFile));
  244.     char *head=
  245.     "HTTP/1.0 200 WWWOFFLE Control Page\r\n"
  246.     "Content-type: text/html\r\n"
  247.     "\r\n"
  248.     "<HTML>\n"
  249.     "<HEAD>\n"
  250.     "<TITLE>WWWOFFLE - Interactive Control Page</TITLE>\n"
  251.     "</HEAD>\n"
  252.     "<BODY>\n"
  253.     "<H1 align=center>WWWOFFLE Interactive Control Page</H1>\n"
  254.     "This page is equivalent to using <b>wwwoffle</b> on the command line\n"
  255.     "<pre>\n";
  256.     char *middle=
  257.     "</pre>\n"
  258.     "The output of this command is:\n"
  259.     "<pre>\n";
  260.     char *tail=
  261.     "</pre>\n"
  262.     "<p align=center>[<a href=\"/control/\">Back to the Control page</a>]</p>"
  263.     "</BODY>\n"
  264.     "</HTML>\n";
  265.  
  266.     write_string(fd,head);
  267.  
  268.     sprintf(string,"wwwoffle %s -c %s\n",command,ConfigFile);
  269.     write_string(fd,string);
  270.  
  271.     /* Send the message. */
  272.  
  273.     if(PassWord)
  274.        write_formatted(socket,"WWWOFFLE PASSWORD %s\r\n",PassWord);
  275.  
  276.     if(action==Online)
  277.        write_string(socket,"WWWOFFLE ONLINE\r\n");
  278.     else if(action==Autodial)
  279.        write_string(socket,"WWWOFFLE AUTODIAL\r\n");
  280.     else if(action==Offline)
  281.        write_string(socket,"WWWOFFLE OFFLINE\r\n");
  282.     else if(action==Fetch)
  283.        write_string(socket,"WWWOFFLE FETCH\r\n");
  284.     else if(action==Config)
  285.        write_string(socket,"WWWOFFLE CONFIG\r\n");
  286.     else if(action==Purge)
  287.        write_string(socket,"WWWOFFLE PURGE\r\n");
  288.  
  289.     write_string(fd,middle);
  290.  
  291.     while((buffer=read_line_or_timeout(socket,buffer)))
  292.        write_string(fd,buffer);
  293.  
  294.     write_string(fd,tail);
  295.    }
  296. }
  297.  
  298.  
  299. /*++++++++++++++++++++++++++++++++++++++
  300.   The control page that deletes a cached page or a request.
  301.  
  302.   int fd The file descriptor to write to.
  303.  
  304.   char *args The arguments specified.
  305.   ++++++++++++++++++++++++++++++++++++++*/
  306.  
  307. static void DeleteControlPage(int fd,char *args)
  308. {
  309.  char *head=
  310.  "HTTP/1.0 200 WWWOFFLE Control Page\r\n"
  311.  "Content-type: text/html\r\n"
  312.  "\r\n"
  313.  "<HTML>\n"
  314.  "<HEAD>\n"
  315.  "<TITLE>WWWOFFLE - Delete Page</TITLE>\n"
  316.  "</HEAD>\n"
  317.  "<BODY>\n"
  318.  "<H1 align=center>WWWOFFLE Delete Page</H1>\n";
  319.  char *tail=
  320.  "<p align=center>[<a href=\"/control/\">Go to the Control page</a>]</p>"
  321.  "</BODY>\n"
  322.  "</HTML>\n";
  323.  char *url=NULL,*req=NULL,*mon=NULL,*password=NULL,*copy;
  324.  int i,all=0;
  325.  
  326.  copy=(char*)malloc(strlen(args)+1);
  327.  strcpy(copy,args);
  328.  
  329.  for(i=0;copy[i];i++)
  330.    {
  331.     if(i!=0 && copy[i-1]=='&')
  332.        copy[i-1]=0;
  333.     if(i==0 || copy[i-1]==0)
  334.       {
  335.        if(!strncmp("password=",©[i],9))
  336.           password=copy+i+9;
  337.        if(!strncmp("url=",©[i],4))
  338.           url=copy+i+4;
  339.        if(!strncmp("mon=",©[i],4))
  340.           mon=copy+i+4;
  341.        if(!strncmp("req=",©[i],4))
  342.           req=copy+i+4;
  343.        if(!strncmp("all=yes",©[i],7))
  344.           all=1;
  345.       }
  346.    }
  347.  
  348.  if((!url && !mon && !req) || (url && mon) || (url && req) || (mon && req) || (mon && all) || (password && (all || !req)))
  349.    {
  350.     IllegalControlPage(fd,"delete",args);
  351.     PrintMessage(Important,"Invalid interactive delete page requested; args='%s'.",args);
  352.    }
  353.  else
  354.    {
  355.     if(password)
  356.       {
  357.        char *decreq=UrlDecode(req,0);
  358.        URL *Url=SplitURL(decreq);
  359.        char *hash=HashOutgoingSpoolFile(Url);
  360.  
  361.        FreeURL(Url);
  362.        free(decreq);
  363.  
  364.        if(!hash || strcmp(password,hash))
  365.          {
  366.           char *controlurl=(char*)malloc(16+strlen(args));
  367.           sprintf(controlurl,"delete?%s",args);
  368.           ControlAuthFail(fd,controlurl);
  369.           free(controlurl);
  370.           PrintMessage(Important,"Interactive control webpage delete with password failed.");
  371.           return;
  372.          }
  373.       }
  374.  
  375.     if(req && all)
  376.       {
  377.        char *err=DeleteOutgoingSpoolFile(NULL);
  378.  
  379.        write_string(fd,head);
  380.        if(err)
  381.           write_formatted(fd,"There was an error while processing the delete request for all outgoing requests.\n"
  382.                              "<br>The error message was\n"
  383.                              "<br><b>%s</b>\n",
  384.                              err);
  385.        else
  386.           write_string(fd,"All the requested files have been removed from the outgoing directory.\n");
  387.        write_string(fd,tail);
  388.       }
  389.     else if(req)
  390.       {
  391.        char *decreq=UrlDecode(req,0);
  392.        URL *Url=SplitURL(decreq);
  393.  
  394.        if(Url->Protocol)
  395.          {
  396.           char *err=DeleteOutgoingSpoolFile(Url);
  397.  
  398.           write_string(fd,head);
  399.           if(err)
  400.              write_formatted(fd,"There was an error while processing the delete request for the page\n"
  401.                                 "<br><b><tt>%s</tt></b>\n"
  402.                                 "<br>in the outgoing directory.  The error message was\n"
  403.                                 "<br><b>%s</b>\n",
  404.                                 Url->name,err);
  405.           else
  406.              write_formatted(fd,"The URL\n"
  407.                                 "<br><b><tt>%s</tt></b>\n"
  408.                                 "<br>has been removed from the outgoing directory.\n",
  409.                                 Url->name);
  410.           write_string(fd,tail);
  411.          }
  412.        else
  413.          {
  414.           char *controlurl=(char*)malloc(24+strlen(args));
  415.           sprintf(controlurl,"/control/delete?%s",args);
  416.           IllegalProto(fd,controlurl,Url->proto);
  417.           free(controlurl);
  418.          }
  419.  
  420.        FreeURL(Url);
  421.        free(decreq);
  422.       }
  423.     else if(url)
  424.       {
  425.        char *decurl=UrlDecode(url,0);
  426.        URL *Url=SplitURL(decurl);
  427.  
  428.        if(Url->Protocol)
  429.          {
  430.           char *err=DeleteWebpageSpoolFile(Url,all);
  431.  
  432.           write_string(fd,head);
  433.           if(err && all)
  434.              write_formatted(fd,"There was an error while processing the delete request for all the pages from host\n"
  435.                                 "<br><b><tt>%s</tt></b>\n"
  436.                                 "<br>in the cache.  The error message was\n"
  437.                                 "<br><b>%s</b>\n",
  438.                                 Url->name,err);
  439.           else if(err)
  440.              write_formatted(fd,"There was an error while processing the delete request for the page\n"
  441.                                 "<br><b><tt>%s</tt></b>\n"
  442.                                 "<br>in the cache.  The error message was\n"
  443.                                 "<br><b>%s</b>\n",
  444.                                 Url->name,err);
  445.           else if(all)
  446.              write_formatted(fd,"All of the pages from host\n"
  447.                                 "<br><b><tt>%s</tt></b>\n"
  448.                                 "<br>in the cache have been deleted.\n",
  449.                                 Url->name);
  450.           else
  451.              write_formatted(fd,"The page\n"
  452.                                 "<br><b><tt>%s</tt></b>\n"
  453.                                 "<br>in the cache has been deleted.\n",
  454.                                 Url->name);
  455.           write_string(fd,tail);
  456.  
  457.           DeleteLastTimeSpoolFile(Url);
  458.          }
  459.        else
  460.          {
  461.           char *controlurl=(char*)malloc(24+strlen(args));
  462.           sprintf(controlurl,"/control/delete?%s",args);
  463.           IllegalProto(fd,controlurl,Url->proto);
  464.           free(controlurl);
  465.          }
  466.  
  467.        FreeURL(Url);
  468.        free(decurl);
  469.       }
  470.     else /* mon */
  471.       {
  472.        char *decmon=UrlDecode(mon,0);
  473.        URL *Url=SplitURL(decmon);
  474.  
  475.        if(Url->Protocol)
  476.          {
  477.           char *err=DeleteMonitorSpoolFile(Url);
  478.  
  479.           write_string(fd,head);
  480.           if(err)
  481.              write_formatted(fd,"There was an error while processing the delete request for the URL\n"
  482.                                 "<br><b><tt>%s</tt></b>\n"
  483.                                 "<br>in the monitored list.  The error message was\n"
  484.                                 "<br><b>%s</b>\n",
  485.                                 Url->name,err);
  486.           else
  487.              write_formatted(fd,"The page\n"
  488.                                 "<br><b><tt>%s</tt></b>\n"
  489.                                 "<br>in the monitored list has been deleted.\n",
  490.                                 Url->name);
  491.           write_string(fd,tail);
  492.          }
  493.        else
  494.          {
  495.           char *controlurl=(char*)malloc(24+strlen(args));
  496.           sprintf(controlurl,"/control/delete?%s",args);
  497.           IllegalProto(fd,controlurl,Url->proto);
  498.           free(controlurl);
  499.          }
  500.  
  501.        FreeURL(Url);
  502.        free(decmon);
  503.       }
  504.    }
  505. }
  506.  
  507.  
  508. /*++++++++++++++++++++++++++++++++++++++
  509.   Inform the user that the specified control page is illegal.
  510.  
  511.   int fd The file descriptor to write to.
  512.  
  513.   char *path The specified path.
  514.  
  515.   char *args The specified arguments.
  516.   ++++++++++++++++++++++++++++++++++++++*/
  517.  
  518. static void IllegalControlPage(int fd,char *path,char *args)
  519. {
  520.  char *head=
  521.  "HTTP/1.0 404 WWWOFFLE Illegal Control Page\r\n"
  522.  "Content-type: text/html\r\n"
  523.  "\r\n"
  524.  "<HTML>\n"
  525.  "<HEAD>\n"
  526.  "<TITLE>WWWOFFLE - Illegal Interactive Control Page</TITLE>\n"
  527.  "</HEAD>\n"
  528.  "<BODY>\n"
  529.  "<H1 align=center>WWWOFFLE Illegal Interactive Control Page</H1>\n"
  530.  "<p align=center>\n"
  531.  "Your request for the control URL\n"
  532.  "<br><b><tt>\n";
  533.  char *tail=
  534.  "\n"
  535.  "</tt></b><br>\n"
  536.  "is illegal, select the link below for the main interactive control page.\n"
  537.  "<br>\n"
  538.  "<a href=\"/control/\">/control/</a>\n"
  539.  "</BODY>\n"
  540.  "</HTML>\n";
  541.  
  542.  write_string(fd,head);
  543.  if(args)
  544.     write_formatted(fd,"/control/%s?%s",path,args);
  545.  else
  546.     write_formatted(fd,"/control/%s",path);
  547.  write_string(fd,tail);
  548. }
  549.  
  550.  
  551. /*++++++++++++++++++++++++++++++++++++++
  552.   Inform the user that the authorisation failed.
  553.  
  554.   int fd The file descriptor to write to.
  555.  
  556.   char *path The specified path.
  557.   ++++++++++++++++++++++++++++++++++++++*/
  558.  
  559. static void ControlAuthFail(int fd,char *path)
  560. {
  561.  char *head=
  562.  "HTTP/1.0 401 WWWOFFLE Authorisation Failed\r\n"
  563.  "WWW-Authenticate: Basic realm=\"control\"\r\n"
  564.  "Content-type: text/html\r\n"
  565.  "\r\n"
  566.  "<HTML>\n"
  567.  "<HEAD>\n"
  568.  "<TITLE>WWWOFFLE - Authorisation Failed</TITLE>\n"
  569.  "</HEAD>\n"
  570.  "<BODY>\n"
  571.  "<H1 align=center>WWWOFFLE Authorisation Failed</H1>\n"
  572.  "<p align=center>\n"
  573.  "Your request for the interactive control URL\n"
  574.  "<br><b><tt>\n";
  575.  char *tail=
  576.  "\n"
  577.  "</tt></b><br>\n"
  578.  "requires a password and you have failed to be authorised.\n"
  579.  "<p align=center>[<a href=\"/\">Back to the Welcome page</a>]</p>\n"
  580.  "</BODY>\n"
  581.  "</HTML>\n";
  582.  
  583.  write_string(fd,head);
  584.  write_formatted(fd,"/control/%s",path);
  585.  write_string(fd,tail);
  586. }
  587.  
  588.  
  589. /*++++++++++++++++++++++++++++++++++++++
  590.   Try to match the authorisation password against the actual one.
  591.  
  592.   int MatchPassword Returns true if the password is OK.
  593.  
  594.   char *try The attempted password.
  595.  
  596.   char *actual The actual password.
  597.   ++++++++++++++++++++++++++++++++++++++*/
  598.  
  599. static int MatchPassword(char *try,char *actual)
  600. {
  601.  int ok=0,l;
  602.  char *decoded=Base64Decode(try,&l);
  603.  char *colon;
  604.  
  605.  colon=strchr(decoded,':');
  606.  
  607.  if(colon && !strcmp(colon+1,actual))
  608.     ok=1;
  609.  
  610.  free(decoded);
  611.  
  612.  return(ok);
  613. }
  614.