⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sflhttp.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
                f_tmp = fopen (tmp_name, "wb");
              }
          }
        p_next = (char *) memfind ((byte *) p_data,
                          /*  read_size                                      */
                          MULTI_BUFFER_SIZE + REST_BUFFER_SIZE - (p_data - buffer),
                          (byte *) separator, sep_size, FALSE);

        if (p_next != NULL)
          {
            /*  The next attribute-value pair was found                      */
            *p_next = '\0';
            save_multipart_header (table, header_tab, p_data, tmp_name,
                                   local_format);
            if (f_tmp)
              {
                /* Special case:
                   The next attribute value is found AND "f_tmp" is opened.
                   That means that the download file is completely in the
                   buffer and so we can save it to disk.
                 */
                fwrite (p_data, p_next - p_data, 1, f_tmp);
                fclose (f_tmp);
                f_tmp = NULL;
                if (get_file_size (tmp_name) == 0)
                    file_delete (tmp_name);

                /* Now we need to check the buffer.  If the buffer is full
                   then we must read the rest of "f_source". The rest will
                   be written into the the buffer at REST_BUFFER_SIZE.
                 */
                if (read_size == MULTI_BUFFER_SIZE)
                    rest_read_size = fread (&buffer [MULTI_BUFFER_SIZE], 1,
                                            REST_BUFFER_SIZE, f_source);
              }
            p_next += sep_size;

            /*  Found end of file marker                                     */
            if (*p_next == '-' && *(p_next + 1) == '-')
              {
                if (f_tmp)
                  {
                    fclose (f_tmp);
                    f_tmp = NULL;
                    if (get_file_size (tmp_name) == 0)
                        file_delete (tmp_name);
                  }
                break;
              }
            else
                while (*p_next == '\r' || *p_next == '\n')
                    p_next++;
          }
        else
          {
            if (f_tmp)
                fwrite (p_data, &buffer [read_size - sep_size ] - p_data,
                        1, f_tmp);
            offset = 0;
            while (read_size > 0 && p_next == NULL)
              {
                memmove (buffer, &buffer [read_size - sep_size + offset ],
                                 sep_size);
                read_size = fread (&buffer [sep_size], 1,
                                   MULTI_BUFFER_SIZE - sep_size, f_source);
                p_next = (char *) memfind ((byte *) buffer,
                                  read_size + sep_size,
                                  (byte *) separator, sep_size, FALSE);               
                if (p_next != NULL)
                  {
                    /*  We need to test if the buffer is large enough.  If
                        not, we use the additional buffer size starting at
                        position REST_BUFFER_SIZE.
                     */
                    if (read_size == (MULTI_BUFFER_SIZE - sep_size))
                      {
                        /* Attach the rest of the file */
                        rest_read_size = fread (&buffer [MULTI_BUFFER_SIZE], 1,
                                                REST_BUFFER_SIZE, f_source);
                      }
   
                    *p_next = '\0';
                    save_multipart_header (table, header_tab,
                                           p_data, tmp_name, local_format);
                    if (f_tmp)
                      {
                        fwrite (buffer, p_next - buffer, 1, f_tmp);
                        fclose (f_tmp);
                        f_tmp = NULL;
                        if (get_file_size (tmp_name) == 0)
                            file_delete (tmp_name);
                      }
                    p_next += sep_size;

                   /*  Found end of file marker                              */
                   if (*p_next == '-' && *(p_next + 1) == '-')
                     {
                       read_size = 0;
                       break;
                     }
                   else
                       while (*p_next == '\r' || *p_next == '\n')
                           p_next++;
                   read_size += sep_size;
                  }
                else
                  {
                    /*  We did not find the next separator, so we write the
                        file and continue.
                     */
                    if (f_tmp)
                        fwrite (buffer, read_size, 1, f_tmp);
                    offset = sep_size;
                  }

              }
          }
      }
    if (f_tmp)
      {
        fclose (f_tmp);
        if (get_file_size (tmp_name) == 0)
            file_delete (tmp_name);
      }
    sym_delete_table (header_tab);
    fclose (f_source);
    mem_free (buffer);

    descr = http_multipart2url (table);
    sym_delete_table (table);

    return (descr);
}


/*  -------------------------------------------------------------------------
    Function: http_multipart2url

    Synopsis: Convert a symbol table to a string in format :
              name=value&name=value&name=value ....
    -------------------------------------------------------------------------*/

static DESCR *
http_multipart2url  (const SYMTAB *symtab)
{
    DESCR
        *descr;                         /*  Formatted descriptor             */
    SYMBOL
        *symbol;                        /*  Pointer to symbol                */
    char
        *p_char,
        *p_val;
    qbyte
        buffer_length = 0;

    if (!symtab)
        return (NULL);                  /*  Return NULL if argument is null  */

    /*  Calculate length of buffer                                           */
    for (symbol = symtab-> symbols; symbol; symbol = symbol-> next)
        buffer_length += strlen (symbol-> name) + strlen (symbol-> value) + 2;

    /*  On 16-bit systems, check that buffer will fit into max. block size   */
#   if (UINT_MAX == 0xFFFFU)
    if (buffer_length > UINT_MAX - 32)
        return (NULL);
#   endif

    /*  Now allocate the descriptor                                          */
    descr = mem_descr (NULL, (size_t) buffer_length + 1);
    if (descr == NULL)
        return (NULL);

    p_char = (char *) descr-> data;
    for (symbol = symtab-> symbols; symbol; symbol = symbol-> next)
      {
        if (symbol != symtab-> symbols)
            *p_char++ = '&';
        p_val = symbol-> name;
        while (*p_val)
            *p_char++ = *p_val++;
        *p_char++ = '=';
        p_val = symbol-> value;
        while (*p_val)
            *p_char++ = *p_val++;
      }
    *p_char = '\0';

    return (descr);
}


/*  -------------------------------------------------------------------------
    Function: save_multipart_header

    Synopsis: Store field name and value in symbol table.
    -------------------------------------------------------------------------*/

static void
save_multipart_header (SYMTAB *table, SYMTAB *header, char *data,
                       char *tmp_name, const char *local_format)
{
    SYMBOL
        *sym_filename,
        *symbol;
    char
        *copyfmt,
        *percent,
        *tmp_val,
        *value;

    /* Check if is a file uploaded or form field                             */
    if ((sym_filename = sym_lookup_symbol (header, "filename")) != NULL)
      {
        symbol = sym_lookup_symbol (header, "name");
        if (symbol)
          {
            value = http_escape (sym_filename-> value, NULL, 0);
            if (value)
              {
                sym_assume_symbol (table, symbol-> value, value);
                mem_free (value);
              }
            /*  Construct temporary name by replacing %s in the format string
             *  by the variable name.  We don't use sprintf because it's too
             *  dangerous here: the format string can cause havoc.
             */
            copyfmt = mem_strdup (local_format);
            percent = strchr (copyfmt, '%');
            if (percent && percent [1] == 's')
              {
                percent [0] = '\0';
                tmp_val = xstrcpy (NULL, copyfmt, symbol-> value, percent + 2, NULL);
              }
            else
                tmp_val = xstrcpy (NULL, symbol-> value, "_tmp", NULL);

            value = http_escape (tmp_name, NULL, 0);
            if (value)
              {
                sym_assume_symbol (table, tmp_val, value);
                mem_free (value);
              }
            mem_strfree (&tmp_val);
            mem_strfree (&copyfmt);
          }
      }
    else
      {
        symbol = sym_lookup_symbol (header, "name");
        if (symbol)
          {
            value = http_escape (data, NULL, 0);
            if (value)
              {
                sym_assume_symbol (table, symbol-> value, value);
                mem_free (value);
              }
          }
      }
}


/*  -------------------------------------------------------------------------
    Function: multipart_decode_header

    Synopsis: Decode mime header of a part.
    -------------------------------------------------------------------------*/

static void
multipart_decode_header (char *header, SYMTAB *table)
{
    char
        *p,
        *variable,
        *value = "";

    ASSERT (header);
    ASSERT (table);

    p        = header;
    variable = header;
    while (*p)
      {
        if ((*p == ':' && *(p + 1) == ' ')
        ||   *p == '=')
          {
            *p++ = '\0';
            if (*p == ' ' || *p == '"')
                p++;
            value = p;
          }
        else
        if (*p == ';' || *p == '\r'||  *p == '\n')
          {
            if (*(p - 1) == '"')
                *(p - 1) = '\0';
            else
                *p = '\0';
            http_unescape (value, NULL);
            sym_assume_symbol (table, variable, value);
            p++;
            while (*p == ' ' || *p == '\r' || *p == '\n')
                p++;
            variable = p;
          }
        p++;
      }
    if (p != header && *(p - 1) == '"')
        *(p - 1) = '\0';
    http_unescape (value, NULL);
    sym_assume_symbol (table, variable, value);
}


/*  ---------------------------------------------------------------------[<]-
    Function: is_full_url

    Synopsis: If the specified URI string starts with a URL scheme, returns
    TRUE, else returns FALSE.  A schema is one or more of [A-Za-z0-9+-.]
    followed by a ':'.
    ---------------------------------------------------------------------[>]-*/

Bool
is_full_url (const char *string)
{
    Bool
        scheme_size = 0;

    ASSERT (string);
    while (*string)
      {
        if (isalpha (*string)
        ||  isdigit (*string)
        ||  *string == '+'
        ||  *string == '-'
        ||  *string == '.')
            scheme_size++;              /*  So far, a valid scheme name      */
        else
        if (*string == ':')
            return (scheme_size > 0);   /*  Okay if ':' was not first char   */
        else
            return (FALSE);             /*  No scheme name found             */
        string++;
      }
    return (FALSE);                     /*  End of string but no scheme      */
}


/*  ---------------------------------------------------------------------[<]-
    Function: build_full_url

    Synopsis: If the specified URI string does not start with a URL schema
    or a directory delimiter, we add the path of the base URI, and return
    the resulting full URI.  This is provided as a freshly-allocated string
    w

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -