Ejemplo n.º 1
0
static char *
local_quote_string (const char *file, bool no_html_quote)
{
  const char *from;
  char *newname, *to;

  char *any = strpbrk (file, "?#%;");
  if (!any)
    return no_html_quote ? strdup (file) : html_quote_string (file);

  /* Allocate space assuming the worst-case scenario, each character
     having to be quoted.  */
  to = newname = (char *)alloca (3 * strlen (file) + 1);
  newname[0] = '\0';
  for (from = file; *from; from++)
    switch (*from)
      {
      case '%':
        *to++ = '%';
        *to++ = '2';
        *to++ = '5';
        break;
      case '#':
        *to++ = '%';
        *to++ = '2';
        *to++ = '3';
        break;
      case ';':
        *to++ = '%';
        *to++ = '3';
        *to++ = 'B';
        break;
      case '?':
        if (opt.adjust_extension)
          {
            *to++ = '%';
            *to++ = '3';
            *to++ = 'F';
            break;
          }
        /* fallthrough */
      default:
        *to++ = *from;
      }
  *to = '\0';

  return no_html_quote ? strdup (newname) : html_quote_string (newname);
}
Ejemplo n.º 2
0
static char *
local_quote_string (const char *file)
{
  const char *file_sans_qmark;
  int qm;

  if (!opt.html_extension)
    return html_quote_string (file);

  qm = count_char (file, '?');

  if (qm)
    {
      const char *from = file;
      char *to, *newname;

      /* qm * 2 because we replace each question mark with "%3F",
	 i.e. replace one char with three, hence two more.  */
      int fsqlen = strlen (file) + qm * 2;

      to = newname = (char *)alloca (fsqlen + 1);
      for (; *from; from++)
	{
	  if (*from != '?')
	    *to++ = *from;
	  else
	    {
	      *to++ = '%';
	      *to++ = '3';
	      *to++ = 'F';
	    }
	}
      assert (to - newname == fsqlen);
      *to = '\0';

      file_sans_qmark = newname;
    }
  else
    file_sans_qmark = file;

  return html_quote_string (file_sans_qmark);
}
Ejemplo n.º 3
0
/* The function creates an HTML index containing references to given
   directories and files on the appropriate host.  The references are
   FTP.  */
uerr_t
ftp_index (const char *file, struct urlinfo *u, struct fileinfo *f)
{
    FILE *fp;
    char *upwd;
    char *htclfile;		/* HTML-clean file name */

    if (!opt.dfp)
    {
        fp = fopen (file, "wb");

        if (!fp)
        {
            logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
            return FOPENERR;
        }
    }
    else
        fp = opt.dfp;

    if (u->user)
    {
        char *tmpu, *tmpp;        /* temporary, clean user and passwd */

        tmpu = CLEANDUP (u->user);
        tmpp = u->passwd ? CLEANDUP (u->passwd) : NULL;
        upwd = (char *)xmalloc (strlen (tmpu)
                                + (tmpp ? (1 + strlen (tmpp)) : 0) + 2);

        sprintf (upwd, "%s%s%s@", tmpu, tmpp ? ":" : "", tmpp ? tmpp : "");

        free (tmpu);
        FREE_MAYBE (tmpp);
    }
    else
        upwd = xstrdup ("");

    fprintf (fp, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
    fprintf (fp, "<html>\n<head>\n<title>");
    fprintf (fp, _("Index of /%s on %s:%d"), u->dir, u->host, u->port);
    fprintf (fp, "</title>\n</head>\n<body>\n<h1>");
    fprintf (fp, _("Index of /%s on %s:%d"), u->dir, u->host, u->port);
    fprintf (fp, "</h1>\n<hr>\n<pre>\n");

    while (f)
    {
        fprintf (fp, "  ");
        if (f->tstamp != -1)
        {
            /* #### Should we translate the months? */
            static char *months[] =
            {
                "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
            };
            struct tm *ptm = localtime ((time_t *)&f->tstamp);

            fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],
                     ptm->tm_mday);
            if (ptm->tm_hour)
                fprintf (fp, "%02d:%02d  ", ptm->tm_hour, ptm->tm_min);
            else
                fprintf (fp, "       ");
        }
        else
            fprintf (fp, _("time unknown       "));

        switch (f->type)
        {
        case FT_PLAINFILE:
            fprintf (fp, _("File        "));
            break;
        case FT_DIRECTORY:
            fprintf (fp, _("Directory   "));
            break;
        case FT_SYMLINK:
            fprintf (fp, _("Link        "));
            break;
        default:
            fprintf (fp, _("Not sure    "));
            break;
        }

        htclfile = html_quote_string (f->name);
        fprintf (fp, "<a href=\"ftp://%s%s:%hu", upwd, u->host, u->port);
        if (*u->dir != '/')
            putc ('/', fp);
        fprintf (fp, "%s", u->dir);
        if (*u->dir)
            putc ('/', fp);
        fprintf (fp, "%s", htclfile);
        if (f->type == FT_DIRECTORY)
            putc ('/', fp);
        fprintf (fp, "\">%s", htclfile);
        if (f->type == FT_DIRECTORY)
            putc ('/', fp);
        fprintf (fp, "</a> ");
        if (f->type == FT_PLAINFILE)
            fprintf (fp, _(" (%s bytes)"), legible (f->size));
        else if (f->type == FT_SYMLINK)
            fprintf (fp, "-> %s", f->linkto ? f->linkto : "(nil)");

        putc ('\n', fp);
        free (htclfile);
        f = f->next;
    }

    fprintf (fp, "</pre>\n</body>\n</html>\n");
    free (upwd);

    if (!opt.dfp)
        fclose (fp);
    else
        fflush (fp);

    return FTPOK;
}
Ejemplo n.º 4
0
/* Change the links in one file.  LINKS is a list of links in the
   document, along with their positions and the desired direction of
   the conversion.  */
static void
convert_links (const char *file, struct urlpos *links)
{
    struct file_memory *fm;
    FILE *fp;
    const char *p;
    downloaded_file_t downloaded_file_return;

    struct urlpos *link;
    int to_url_count = 0, to_file_count = 0;

    logprintf (LOG_VERBOSE, _("Converting %s... "), file);

    {
        /* First we do a "dry run": go through the list L and see whether
           any URL needs to be converted in the first place.  If not, just
           leave the file alone.  */
        int dry_count = 0;
        struct urlpos *dry;
        for (dry = links; dry; dry = dry->next)
            if (dry->convert != CO_NOCONVERT)
                ++dry_count;
        if (!dry_count)
        {
            logputs (LOG_VERBOSE, _("nothing to do.\n"));
            return;
        }
    }

    fm = wget_read_file (file);
    if (!fm)
    {
        logprintf (LOG_NOTQUIET, _("Cannot convert links in %s: %s\n"),
                   file, strerror (errno));
        return;
    }

    downloaded_file_return = downloaded_file (CHECK_FOR_FILE, file);
    if (opt.backup_converted && downloaded_file_return)
        write_backup_file (file, downloaded_file_return);

    /* Before opening the file for writing, unlink the file.  This is
       important if the data in FM is mmaped.  In such case, nulling the
       file, which is what fopen() below does, would make us read all
       zeroes from the mmaped region.  */
    if (unlink (file) < 0 && errno != ENOENT)
    {
        logprintf (LOG_NOTQUIET, _("Unable to delete %s: %s\n"),
                   quote (file), strerror (errno));
        wget_read_file_free (fm);
        return;
    }
    /* Now open the file for writing.  */
    fp = fopen (file, "wb");
    if (!fp)
    {
        logprintf (LOG_NOTQUIET, _("Cannot convert links in %s: %s\n"),
                   file, strerror (errno));
        wget_read_file_free (fm);
        return;
    }

    /* Here we loop through all the URLs in file, replacing those of
       them that are downloaded with relative references.  */
    p = fm->content;
    for (link = links; link; link = link->next)
    {
        char *url_start = fm->content + link->pos;

        if (link->pos >= fm->length)
        {
            DEBUGP (("Something strange is going on.  Please investigate."));
            break;
        }
        /* If the URL is not to be converted, skip it.  */
        if (link->convert == CO_NOCONVERT)
        {
            DEBUGP (("Skipping %s at position %d.\n", link->url->url, link->pos));
            continue;
        }

        /* Echo the file contents, up to the offending URL's opening
           quote, to the outfile.  */
        fwrite (p, 1, url_start - p, fp);
        p = url_start;

        switch (link->convert)
        {
        case CO_CONVERT_TO_RELATIVE:
            /* Convert absolute URL to relative. */
        {
            char *newname = construct_relative (file, link->local_name);
            char *quoted_newname = local_quote_string (newname,
                                   link->link_css_p);

            if (link->link_css_p)
                p = replace_plain (p, link->size, fp, quoted_newname);
            else if (!link->link_refresh_p)
                p = replace_attr (p, link->size, fp, quoted_newname);
            else
                p = replace_attr_refresh_hack (p, link->size, fp, quoted_newname,
                                               link->refresh_timeout);

            DEBUGP (("TO_RELATIVE: %s to %s at position %d in %s.\n",
                     link->url->url, newname, link->pos, file));
            xfree (newname);
            xfree (quoted_newname);
            ++to_file_count;
            break;
        }
        case CO_CONVERT_TO_COMPLETE:
            /* Convert the link to absolute URL. */
        {
            char *newlink = link->url->url;
            char *quoted_newlink = html_quote_string (newlink);

            if (link->link_css_p)
                p = replace_plain (p, link->size, fp, newlink);
            else if (!link->link_refresh_p)
                p = replace_attr (p, link->size, fp, quoted_newlink);
            else
                p = replace_attr_refresh_hack (p, link->size, fp, quoted_newlink,
                                               link->refresh_timeout);

            DEBUGP (("TO_COMPLETE: <something> to %s at position %d in %s.\n",
                     newlink, link->pos, file));
            xfree (quoted_newlink);
            ++to_url_count;
            break;
        }
        case CO_NULLIFY_BASE:
            /* Change the base href to "". */
            p = replace_attr (p, link->size, fp, "");
            break;
        case CO_NOCONVERT:
            abort ();
            break;
        }
    }

    /* Output the rest of the file. */
    if (p - fm->content < fm->length)
        fwrite (p, 1, fm->length - (p - fm->content), fp);
    fclose (fp);
    wget_read_file_free (fm);

    logprintf (LOG_VERBOSE, "%d-%d\n", to_file_count, to_url_count);
}