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

  1. /***************************************
  2.   $Header: /home/amb/wwwoffle/RCS/refresh.c 2.24 1998/02/23 20:10:20 amb Exp $
  3.  
  4.   WWWOFFLE - World Wide Web Offline Explorer - Version 2.1.
  5.   The HTML interactive page to refresh a URL.
  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. static void RefreshFormPage(int fd,char *args);
  30. static int  RefreshFormParse(int fd,char *request_body,int is_online);
  31. static void RefreshFormError(int fd,char *body);
  32. static int  RefreshFormRecursive(int fd,char *url,char *method);
  33. static void IllegalRefreshPage(int fd,char *path);
  34.  
  35. static int  RecurseFetchPages(int fd,char *url,char *method);
  36.  
  37.  
  38. /*++++++++++++++++++++++++++++++++++++++
  39.   Send to the client a page to allow refreshes using HTML.
  40.  
  41.   char *RefreshPage Returns a modified URLs for a simple refresh.
  42.  
  43.   int fd The file descriptor of the client.
  44.  
  45.   char *path The path that was specified by the user.
  46.  
  47.   char *args The argument that was appended to the URL.
  48.  
  49.   char *url The url that was requested.
  50.  
  51.   char *request_body A pointer to the HTTP request sent by the browser.
  52.  
  53.   int is_online Set to true if we are online.
  54.   ++++++++++++++++++++++++++++++++++++++*/
  55.  
  56. char *RefreshPage(int fd,char *path,char *args,char *url,char *request_body,int is_online)
  57. {
  58.  char *newurl=NULL;
  59.  
  60.  if(!strcmp("/refresh/",path))
  61.     RefreshFormPage(fd,args);
  62.  else if(!strcmp("/refresh-request/",path))
  63.    {
  64.     if(RefreshFormParse(fd,request_body,is_online))
  65.        newurl=(char*)1;
  66.    }
  67.  else if(!strncmp("/refresh/",path,9))
  68.    {
  69.     char *p,*s,*copy=(char*)malloc(strlen(url)+1);
  70.  
  71.     p=strstr(url,"/refresh/")+9;
  72.     s=strchr(p,'/');
  73.     if(!s)
  74.       {IllegalRefreshPage(fd,path);return((char*)1);}
  75.     *s++=0;
  76.  
  77.     strcpy(copy,p);
  78.     strcat(copy,"://");
  79.     strcat(copy,s);
  80.     newurl=copy;
  81.  
  82.     *--s='/';
  83.    }
  84.  else
  85.    {
  86.     char *copy=(char*)malloc(strlen(path)+1);
  87.     char *slash,*s;
  88.  
  89.     strcpy(copy,path);
  90.  
  91.     slash=strchr(copy+1,'/');
  92.     if(!slash)
  93.       {IllegalRefreshPage(fd,path);return((char*)1);}
  94.     *slash++=0;
  95.  
  96.     s=strchr(slash,'/');
  97.     if(!s)
  98.       {IllegalRefreshPage(fd,path);return((char*)1);}
  99.     *s++=0;
  100.  
  101.     if(is_online)
  102.       {
  103.        char *url=(char*)malloc(strlen(slash)+strlen(s)+(args?strlen(args):0)+8);
  104.        if(args)
  105.           sprintf(url,"%s://%s?%s",slash,s,args);
  106.        else
  107.           sprintf(url,"%s://%s",slash,s);
  108.        if(RecurseFetchPages(fd,url,copy))
  109.           newurl=(char*)1;
  110.        free(url);
  111.       }
  112.     else
  113.       {
  114.        URL *Url=SplitURL(url);
  115.  
  116.        if(Url->Protocol)
  117.          {
  118.           char *new_request=RequestURL(Url->name,NULL);
  119.           int new_outgoing=OpenOutgoingSpoolFile(0);
  120.  
  121.           if(new_outgoing==-1)
  122.              PrintMessage(Warning,"Cannot open the new outgoing request to write.");
  123.           else
  124.             {
  125.              write_string(new_outgoing,new_request);
  126.              CloseOutgoingSpoolFile(new_outgoing,Url);
  127.             }
  128.  
  129.           free(new_request);
  130.          }
  131.  
  132.        FreeURL(Url);
  133.       }
  134.  
  135.     free(copy);
  136.    }
  137.  
  138.  return(newurl);
  139. }
  140.  
  141.  
  142. /*++++++++++++++++++++++++++++++++++++++
  143.   The form that the user enters the details on.
  144.  
  145.   int fd The file descriptor.
  146.  
  147.   char *args The arguments that were on the request for this URL.
  148.   ++++++++++++++++++++++++++++++++++++++*/
  149.  
  150. static void RefreshFormPage(int fd,char *args)
  151. {
  152.  char *head=
  153.  "HTTP/1.0 200 WWWOFFLE Refresh Form\r\n"
  154.  "Content-type: text/html\r\n"
  155.  "\r\n"
  156.  "<HTML>\n"
  157.  "<HEAD>\n"
  158.  "<TITLE>WWWOFFLE - Interactive Refresh Form</TITLE>\n"
  159.  "</HEAD>\n"
  160.  "<BODY>\n"
  161.  "<H1 align=center>WWWOFFLE Interactive Refresh Form</H1>\n"
  162.  "You can use this form to refresh or fetch any URL, either a single one or by following links recursively.\n"
  163.  "<p>\n"
  164.  "<form action=\"/refresh-request/\" method=post>\n"
  165.  "Fetch <select name=\"method\">\n"
  166.  "<option value=\"-none\" selected>this URL only\n"
  167.  "<option value=\"-dir-1\"   >recursively to depth 1 in the same directory\n"
  168.  "<option value=\"-dir-2\"   >recursively to depth 2 in the same directory\n"
  169.  "<option value=\"-dir-3\"   >recursively to depth 3 in the same directory\n"
  170.  "<option value=\"-dir-4\"   >recursively to depth 4 in the same directory\n"
  171.  "<option value=\"-dir-5\"   >recursively to depth 5 in the same directory\n"
  172.  "<option value=\"-host-1\"  >recursively to depth 1 on the same host\n"
  173.  "<option value=\"-host-2\"  >recursively to depth 2 on the same host\n"
  174.  "<option value=\"-host-3\"  >recursively to depth 3 on the same host\n"
  175.  "<option value=\"-host-4\"  >recursively to depth 4 on the same host\n"
  176.  "<option value=\"-any-1\"   >recursively to depth 1 on any host\n"
  177.  "<option value=\"-any-2\"   >recursively to depth 2 on any host\n"
  178.  "<option value=\"-any-3\"   >recursively to depth 3 on any host\n"
  179.  "</select>\n"
  180.  "<br>\n"
  181.  "<input type=\"text\" name=\"url\" value=\"";
  182.  char *middle1=
  183.  "\"size=60>\n"
  184.  "<br>\n"
  185.  "<input name=\"images\" type=\"checkbox\" value=\"-images\" ";
  186.  char *middle2=
  187.  ">Fetch images in the pages\n"
  188.  "<br>\n"
  189.  "<input name=\"frames\" type=\"checkbox\" value=\"-frames\" ";
  190.  char *tail1=
  191.  ">Fetch frames in the pages\n"
  192.  "<br>\n"
  193.  "<input name=\"force\" type=\"checkbox\" value=\"-force\">Force refresh even if already cached"
  194.  "<br>\n"
  195.  "<input type=\"submit\" value=\"Fetch Now\">\n"
  196.  "</form>\n"
  197.  "<p>\n"
  198.  "Notes:\n"
  199.  "<ol>\n"
  200.  "<li>The default protocol is http if none is specified.\n"
  201.  "<li>To get a directory listing using ftp make sure that the path ends with '/'.\n"
  202.  "<li>To finger user@remote.host you should enter the URL as finger://remote.host/user.\n"
  203.  "</ol>\n";
  204.  char *tail2=
  205.  "</BODY>\n"
  206.  "</HTML>\n";
  207.  
  208.  write_string(fd,head);
  209.  if(args)
  210.    {
  211.     char *decargs=UrlDecode(args,0);
  212.     write_string(fd,decargs);
  213.     free(decargs);
  214.    }
  215.  write_string(fd,middle1);
  216.  if(FetchImages)
  217.     write_string(fd,"checked");
  218.  write_string(fd,middle2);
  219.  if(FetchFrames)
  220.     write_string(fd,"checked");
  221.  write_string(fd,tail1);
  222.  if(!args)
  223.     write_string(fd,"<p align=center>[<a href=\"/\">Back to the Welcome page</a>]</p>\n");
  224.  write_string(fd,tail2);
  225. }
  226.  
  227.  
  228. /*++++++++++++++++++++++++++++++++++++++
  229.   Parse the reply from the form.
  230.  
  231.   int RefreshFormParse Returns a true value if there are more pages to get.
  232.  
  233.   int fd The file descriptor of the client.
  234.  
  235.   char *request_body The body of the HTTP request sent by the browser.
  236.  
  237.   int is_online Set to true if we are online.
  238.   ++++++++++++++++++++++++++++++++++++++*/
  239.  
  240. static int RefreshFormParse(int fd,char *request_body,int is_online)
  241. {
  242.  int i;
  243.  int more=0;
  244.  char *copy,*url=NULL,*method=NULL,*total_method,*images="",*frames="",*force="";
  245.  URL *Url;
  246.  
  247.  if(!request_body)
  248.    {
  249.     RefreshFormError(fd,NULL);
  250.     return(0);
  251.    }
  252.  
  253.  copy=(char*)malloc(strlen(request_body)+1);
  254.  strcpy(copy,request_body);
  255.  
  256.  for(i=0;copy[i];i++)
  257.    {
  258.     if(i!=0 && copy[i-1]=='&')
  259.        copy[i-1]=0;
  260.     if(i==0 || copy[i-1]==0)
  261.       {
  262.        if(!strncmp("method=",©[i],7))
  263.           method=©[i+7];
  264.        if(!strncmp("images=",©[i],7))
  265.           images=©[i+7];
  266.        if(!strncmp("frames=",©[i],7))
  267.           frames=©[i+7];
  268.        if(!strncmp("force=",©[i],6))
  269.           force=©[i+6];
  270.        if(!strncmp("url=",©[i],4))
  271.           url=©[i+4];
  272.       }
  273.    }
  274.  
  275.  if(url==NULL || *url==0 || method==NULL)
  276.    {
  277.     RefreshFormError(fd,request_body);
  278.     free(copy);
  279.     return(0);
  280.    }
  281.  
  282.  url=UrlDecode(url,1);
  283.  Url=SplitURL(url);
  284.  
  285.  total_method=(char*)malloc(strlen(request_body));
  286.  strcpy(total_method,"refresh");
  287.  strcat(total_method,method);
  288.  strcat(total_method,images);
  289.  strcat(total_method,frames);
  290.  strcat(total_method,force);
  291.  
  292.  if(is_online)
  293.     more=RefreshFormRecursive(fd,Url->name,total_method);
  294.  else
  295.    {
  296.     URL *new_Url;
  297.     char *new_url;
  298.  
  299.     new_url=(char*)malloc(strlen(request_body)+16);
  300.     sprintf(new_url,"/%s/%s/%s",total_method,Url->proto,Url->hostp);
  301.     new_Url=SplitURL(new_url);
  302.  
  303.     if(new_Url->Protocol)
  304.       {
  305.        char *new_request=RequestURL(new_Url->name,NULL);
  306.        int new_outgoing=OpenOutgoingSpoolFile(0);
  307.  
  308.        if(new_outgoing==-1)
  309.           PrintMessage(Warning,"Cannot open the new outgoing request to write.");
  310.        else
  311.          {
  312.           write_string(new_outgoing,new_request);
  313.           CloseOutgoingSpoolFile(new_outgoing,new_Url);
  314.           WillGetURL(fd,new_Url,0);
  315.          }
  316.  
  317.        free(new_request);
  318.        free(new_url);
  319.       }
  320.  
  321.     FreeURL(new_Url);
  322.    }
  323.  
  324.  free(total_method);
  325.  free(copy);
  326.  
  327.  FreeURL(Url);
  328.  
  329.  return(more);
  330. }
  331.  
  332.  
  333. /*++++++++++++++++++++++++++++++++++++++
  334.   An error with the form.
  335.  
  336.   int fd The file descriptor.
  337.  
  338.   char *body The browser reply that the user entered.
  339.   ++++++++++++++++++++++++++++++++++++++*/
  340.  
  341. static void RefreshFormError(int fd,char *body)
  342. {
  343.  char *head=
  344.  "HTTP/1.0 404 WWWOFFLE Refresh Form Error\r\n"
  345.  "Content-type: text/html\r\n"
  346.  "\r\n"
  347.  "<HTML>\n"
  348.  "<HEAD>\n"
  349.  "<TITLE>WWWOFFLE - Interactive Refresh Form Error</TITLE>\n"
  350.  "</HEAD>\n"
  351.  "<BODY>\n"
  352.  "<H1 align=center>WWWOFFLE Interactive Refresh Form Error</H1>\n"
  353.  "<p align=center>\n";
  354.  char *middle1=
  355.  "The reply from the form that your browser sent did not have a body.\n";
  356.  char *middle2=
  357.  "The reply from the form that your browser sent\n"
  358.  "<br><b><tt>\n";
  359.  char *middle3=
  360.  "\n"
  361.  "</tt></b><br>\n"
  362.  "had an error and could not be parsed.\n";
  363.  char *tail=
  364.  "<p align=center>[<a href=\"/refresh/\">Back to the Refresh page</a>]</p>"
  365.  "</BODY>\n"
  366.  "</HTML>\n";
  367.  
  368.  write_string(fd,head);
  369.  if(!body)
  370.     write_string(fd,middle1);
  371.  else
  372.    {
  373.     write_string(fd,middle2);
  374.     write_string(fd,body);
  375.     write_string(fd,middle3);
  376.    }
  377.  write_string(fd,tail);
  378. }
  379.  
  380.  
  381. /*++++++++++++++++++++++++++++++++++++++
  382.   Fetch pages recursively, and show progress.
  383.  
  384.   int RefreshFormRecursive Returns a true value if there are more pages to get.
  385.  
  386.   int fd The file descriptor to write into.
  387.  
  388.   char *url The URL to fetch.
  389.  
  390.   char *method The method to use.
  391.   ++++++++++++++++++++++++++++++++++++++*/
  392.  
  393. static int RefreshFormRecursive(int fd,char *url,char *method)
  394. {
  395.  int more;
  396.  char *head=
  397.  "HTTP/1.0 200 WWWOFFLE Refresh Recursive Page\r\n"
  398.  "Content-type: text/html\r\n"
  399.  "\r\n"
  400.  "<HTML>\n"
  401.  "<HEAD>\n"
  402.  "<TITLE>WWWOFFLE - Refresh Recursive Page</TITLE>\n"
  403.  "</HEAD>\n"
  404.  "<BODY>\n"
  405.  "<H1 align=center>WWWOFFLE Refresh Recursive Page</H1>\n"
  406.  "Your requested URL\n"
  407.  "<br><b><tt>\n";
  408.  char *middle=
  409.  "\n"
  410.  "</tt></b><br>\n"
  411.  "and the links to the specified depth are being fetched in the background.\n"
  412.  "<pre>\n";
  413.  char *tail=
  414.  "</pre>\n"
  415.  "<p align=center>[<a href=\"/refresh/\">Back to the Refresh page</a>]</p>"
  416.  "</BODY>\n"
  417.  "</HTML>\n";
  418.  
  419.  write_string(fd,head);
  420.  write_string(fd,url);
  421.  write_string(fd,middle);
  422.  
  423.  more=RecurseFetchPages(fd,url,method);
  424.  
  425.  write_string(fd,tail);
  426.  
  427.  return(more);
  428. }
  429.  
  430.  
  431. /*++++++++++++++++++++++++++++++++++++++
  432.   Inform the user that the specified refresh page is illegal.
  433.  
  434.   int fd The file descriptor to write to.
  435.  
  436.   char *path The specified path.
  437.   ++++++++++++++++++++++++++++++++++++++*/
  438.  
  439. static void IllegalRefreshPage(int fd,char *path)
  440. {
  441.  char *head=
  442.  "HTTP/1.0 404 WWWOFFLE Illegal Refresh Page\r\n"
  443.  "Content-type: text/html\r\n"
  444.  "\r\n"
  445.  "<HTML>\n"
  446.  "<HEAD>\n"
  447.  "<TITLE>WWWOFFLE - Illegal Interactive Refresh Page</TITLE>\n"
  448.  "</HEAD>\n"
  449.  "<BODY>\n"
  450.  "<H1 align=center>WWWOFFLE Illegal Interactive Refresh Page</H1>\n"
  451.  "<p align=center>\n"
  452.  "Your request for the refresh URL\n"
  453.  "<br><b><tt>\n";
  454.  char *tail=
  455.  "\n"
  456.  "</tt></b><br>\n"
  457.  "is illegal, select the link below for the main interactive refresh page.\n"
  458.  "<br>\n"
  459.  "<a href=\"/refresh/\">/refresh/</a>\n"
  460.  "</BODY>\n"
  461.  "</HTML>\n";
  462.  
  463.  write_string(fd,head);
  464.  write_formatted(fd,"/%s",path);
  465.  write_string(fd,tail);
  466. }
  467.  
  468.  
  469. /*++++++++++++++++++++++++++++++++++++++
  470.   Fetch pages recursively.
  471.  
  472.   int RecurseFetchPages Returns a true value if there are more pages to get.
  473.  
  474.   int fd The file descriptor to output to (mode==Real).
  475.  
  476.   char *url The url to start at.
  477.  
  478.   char *method The method to use, encoding the depth and other options.
  479.   ++++++++++++++++++++++++++++++++++++++*/
  480.  
  481. static int RecurseFetchPages(int fd,char *url,char *method)
  482. {
  483.  int recursive_depth=0,recursive_mode=0,images=0,frames=0,force=0;
  484.  int more=0,status;
  485.  char *buffer;
  486.  char *dash;
  487.  int socket;
  488.  int parsed=0;
  489.  URL *pageUrl;
  490.  char *request,*line;
  491.  char **list;
  492.  int j;
  493.  char *copy=(char*)malloc(strlen(method)+1);
  494.  
  495.  strcpy(copy,method);
  496.  
  497.  PrintMessage(Debug,"Refresh method='%s'",method);
  498.  
  499.  if(*copy=='-')
  500.     copy++;
  501.  
  502.  do
  503.    {
  504.     if((dash=strchr(copy,'-')))
  505.        *dash=0;
  506.  
  507.     if(!strcmp(copy,"refresh"))
  508.        ;
  509.     else if(!strcmp(copy,"none"))
  510.        ;
  511.     else if(!strcmp(copy,"dir"))
  512.        recursive_mode=1;
  513.     else if(!strcmp(copy,"host"))
  514.        recursive_mode=2;
  515.     else if(!strcmp(copy,"any"))
  516.        recursive_mode=3;
  517.     else if(!strcmp(copy,"images"))
  518.        images=1;
  519.     else if(!strcmp(copy,"frames"))
  520.        frames=1;
  521.     else if(!strcmp(copy,"force"))
  522.        force=1;
  523.     else if(atoi(copy))
  524.        recursive_depth=atoi(copy);
  525.  
  526.     copy=dash+1;
  527.    }
  528.  while(dash);
  529.  
  530.  pageUrl=SplitURL(url);
  531.  
  532.  /* Get the page */
  533.  
  534.  socket=OpenClientSocket("localhost",HTTP_Port);
  535.  init_buffer(socket);
  536.  if(socket==-1)
  537.    {PrintMessage(Warning,"Cannot open connection to wwwoffle proxy.");return(0);}
  538.  
  539.  if(fd>=0)
  540.     write_formatted(fd,"Getting  %s [%s]\n",pageUrl->name,method);
  541.  
  542.  request=RequestURL(pageUrl->name,NULL);
  543.  
  544.  if(force)
  545.    {
  546.     char *copy=(char*)malloc(strlen(request)+24);
  547.     char *eol=strchr(request,'\n');
  548.  
  549.     *eol=0;eol++;
  550.     strcpy(copy,request);
  551.     strcat(copy,"\nPragma: no-cache\r\n");
  552.     strcat(copy,eol);
  553.  
  554.     free(request);
  555.     request=copy;
  556.    }
  557.  
  558.  write_string(socket,request);
  559.  
  560.  line=read_line_or_timeout(socket,NULL);
  561.  if(sscanf(line,"%*s %d",&status)!=1)
  562.     status=404;
  563.  
  564.  parsed=(status>=200 && status<400) && ParseHTML(socket,pageUrl,0);
  565.  
  566.  buffer=(char*)malloc(257);
  567.  
  568.  while(read_data(socket,buffer,256)>0);
  569.  
  570.  free(line);
  571.  free(request);
  572.  free(buffer);
  573.  
  574.  if(images && parsed && (list=ListImages()))
  575.     for(j=0;list[j];j++)
  576.       {
  577.        URL *imageUrl=SplitURL(list[j]);
  578.  
  579.        if(imageUrl->local)
  580.          {FreeURL(imageUrl);continue;}
  581.  
  582.        if(imageUrl->Protocol)
  583.          {
  584.           char *new_request=RequestURL(imageUrl->name,pageUrl->name);
  585.           int new_outgoing=OpenOutgoingSpoolFile(0);
  586.  
  587.           PrintMessage(Debug,"Image=%s",imageUrl->name);
  588.  
  589.           if(new_outgoing==-1)
  590.              PrintMessage(Warning,"Cannot open the new outgoing request to write.");
  591.           else
  592.             {
  593.              write_string(new_outgoing,new_request);
  594.              CloseOutgoingSpoolFile(new_outgoing,imageUrl);
  595.              more=1;
  596.             }
  597.  
  598.           free(new_request);
  599.          }
  600.  
  601.        FreeURL(imageUrl);
  602.       }
  603.  
  604.  if(frames && parsed && (list=ListFrames()))
  605.     for(j=0;list[j];j++)
  606.       {
  607.        char *refresh;
  608.        int recurse=1;
  609.        URL *frameUrl=SplitURL(list[j]);
  610.  
  611.        if(frameUrl->local)
  612.          {FreeURL(frameUrl);continue;}
  613.  
  614.        PrintMessage(Debug,"Frame=%s",frameUrl->name);
  615.  
  616.        if(recursive_mode!=3)
  617.          {
  618.           if(strcmp(pageUrl->host,frameUrl->host))
  619.              recurse=0;
  620.           else
  621.              if(recursive_mode!=2)
  622.                {
  623.                 char *end=pageUrl->path+strlen(pageUrl->path);
  624.  
  625.                 while(end>pageUrl->path)
  626.                    if(*end=='/')
  627.                       break;
  628.                    else
  629.                       end--;
  630.                 if(*end)
  631.                    *++end=0;
  632.                 if(end!=pageUrl->path && strncmp(pageUrl->path,frameUrl->path,end-pageUrl->path))
  633.                    recurse=0;
  634.                }
  635.          }
  636.  
  637.        if(recurse)
  638.          {
  639.           refresh=(char*)malloc(strlen(frameUrl->name)+64);
  640.  
  641.           strcpy(refresh,"/refresh");
  642.           if(images)
  643.              strcat(refresh,"-images");
  644.           if(frames)
  645.              strcat(refresh,"-frames");
  646.           if(force)
  647.              strcat(refresh,"-force");
  648.           if(recursive_depth)
  649.             {
  650.              if(recursive_mode==1)
  651.                 strcat(refresh,"-dir");
  652.              else if(recursive_mode==2)
  653.                 strcat(refresh,"-host");
  654.              else /* recursive_mode==3 */
  655.                 strcat(refresh,"-any");
  656.              sprintf(&refresh[strlen(refresh)],"-%d",recursive_depth);
  657.             }
  658.           if(!images && !frames && !recursive_depth && !force)
  659.              strcat(refresh,"-none");
  660.           strcat(refresh,"/");
  661.           strcat(refresh,frameUrl->proto);
  662.           strcat(refresh,"/");
  663.           strcat(refresh,frameUrl->hostp);
  664.          }
  665.        else
  666.           refresh=frameUrl->hostp;
  667.  
  668.        if(frameUrl->Protocol)
  669.          {
  670.           char *new_request=RequestURL(refresh,pageUrl->name);
  671.           int new_outgoing=OpenOutgoingSpoolFile(0);
  672.  
  673.           if(new_outgoing==-1)
  674.              PrintMessage(Warning,"Cannot open the new outgoing request to write.");
  675.           else
  676.             {
  677.              write_string(new_outgoing,new_request);
  678.              CloseOutgoingSpoolFile(new_outgoing,frameUrl);
  679.              more=1;
  680.             }
  681.  
  682.           free(new_request);
  683.          }
  684.  
  685.        if(refresh!=list[j])
  686.           free(refresh);
  687.        FreeURL(frameUrl);
  688.       }
  689.  
  690.  if(recursive_depth && parsed && (list=ListLinks()))
  691.     for(j=0;list[j];j++)
  692.       {
  693.        char *refresh;
  694.        URL *linkUrl=SplitURL(list[j]);
  695.  
  696.        if(linkUrl->local)
  697.          {FreeURL(linkUrl);continue;}
  698.  
  699.        PrintMessage(Debug,"Link=%s",linkUrl->name);
  700.  
  701.        if(recursive_mode!=3)
  702.          {
  703.           if(strcmp(pageUrl->host,linkUrl->host))
  704.             {FreeURL(linkUrl);continue;}
  705.           else
  706.              if(recursive_mode!=2)
  707.                {
  708.                 char *end=pageUrl->path+strlen(pageUrl->path);
  709.  
  710.                 while(end>pageUrl->path)
  711.                    if(*end=='/')
  712.                       break;
  713.                    else
  714.                       end--;
  715.                 if(*end)
  716.                    *++end=0;
  717.                 if(end!=pageUrl->path && strncmp(pageUrl->path,linkUrl->path,end-pageUrl->path))
  718.                   {FreeURL(linkUrl);continue;}
  719.                }
  720.          }
  721.  
  722.        if(IsNotGotRecursive(linkUrl->proto,linkUrl->host,linkUrl->path))
  723.          {FreeURL(linkUrl);continue;}
  724.  
  725.        refresh=(char*)malloc(strlen(linkUrl->name)+64);
  726.  
  727.        strcpy(refresh,"/refresh");
  728.        if(images)
  729.           strcat(refresh,"-images");
  730.        if(frames)
  731.           strcat(refresh,"-frames");
  732.        if(force)
  733.           strcat(refresh,"-force");
  734.        if(recursive_depth-1)
  735.          {
  736.           if(recursive_mode==1)
  737.              strcat(refresh,"-dir");
  738.           else if(recursive_mode==2)
  739.              strcat(refresh,"-host");
  740.           else /* recursive_mode==3 */
  741.              strcat(refresh,"-any");
  742.           sprintf(&refresh[strlen(refresh)],"-%d",recursive_depth-1);
  743.          }
  744.        if(!images && !frames && !(recursive_depth-1) && !force)
  745.           strcat(refresh,"-none");
  746.        strcat(refresh,"/");
  747.        strcat(refresh,linkUrl->proto);
  748.        strcat(refresh,"/");
  749.        strcat(refresh,linkUrl->hostp);
  750.  
  751.        if(linkUrl->Protocol)
  752.          {
  753.           char *new_request=RequestURL(refresh,pageUrl->name);
  754.           int new_outgoing=OpenOutgoingSpoolFile(0);
  755.  
  756.           if(new_outgoing==-1)
  757.              PrintMessage(Warning,"Cannot open the new outgoing request to write.");
  758.           else
  759.             {
  760.              write_string(new_outgoing,new_request);
  761.              CloseOutgoingSpoolFile(new_outgoing,linkUrl);
  762.              more=1;
  763.             }
  764.  
  765.           free(new_request);
  766.          }
  767.  
  768.        free(refresh);
  769.        FreeURL(linkUrl);
  770.       }
  771.  
  772.  FreeURL(pageUrl);
  773.  return(more);
  774. }
  775.