Exemplo n.º 1
0
MODULE terminate_the_thread (THREAD *thread)
{
    SYMBOL
        *symb_port;
    static char
        port_name [10];

    tcb = thread-> tcb;                 /*  Point to thread's context        */

    if (tcb-> handle)
      {
        close_socket (tcb-> handle);
        tcb-> handle = 0;
      }
    mem_strfree (&tcb-> file_name);
    mem_strfree (&tcb-> pipe);

    if (tcb-> thread_type == master_event)
        sym_delete_table (pasv_port);
    else
    if (tcb-> passive)
      {
        tcb-> data_port -= ip_portbase;
        sprintf (port_name, "%d", tcb-> data_port);
        symb_port = sym_lookup_symbol (pasv_port, port_name);
        if (symb_port)
            sym_delete_symbol (pasv_port, symb_port);
      }
    the_next_event = terminate_event;
}
Exemplo n.º 2
0
MODULE add_user_data_in_client_thread (THREAD *thread)
{
    tcb = thread-> tcb;                 /*  Point to thread's context        */

    add_user_data (tcb, &((TCB *)client_thread-> tcb)-> reply);
    if (tcb-> main_req_type == REQ_TYPE_HOST)
        mem_strfree (&tcb-> ip_value);
    else
        mem_strfree (&tcb-> host_name);
}
Exemplo n.º 3
0
MODULE get_message_passive (THREAD *thread)
{
    tcb = thread-> tcb;                 /*  Point to thread's context        */

    mem_strfree (&tcb-> file_name);
    mem_strfree (&tcb-> pipe);

    exdr_read (thread-> event-> body, SMT_FTPD_PASSIVE, &tcb-> id,
               &tcb-> data_port, &tcb-> data_host);

    tcb-> reply_to      = thread-> event-> sender;
    tcb-> transfer_type = PASSIVE_MODE;
    tcb-> passive       = TRUE;
}
Exemplo n.º 4
0
MODULE create_request_thread (THREAD *thread)
{
    THREAD
        *child;                         /*  Handle to child thread           */
    TCB
        *main_tcb;
    char
        *thread_name = NULL;

    main_tcb = thread-> tcb;

    if (main_tcb-> main_req_type == REQ_TYPE_HOST)
        thread_name = main_tcb-> ip_value;
    else
        thread_name = main_tcb-> host_name;
    if (thread_name == NULL)
        thread_name = "";
    if ((child = thread_create (AGENT_NAME, thread_name)) != NULL)
      {
        event_send (
            &child-> queue-> qid,       /*  Send to child thread queue       */
            &thread-> event-> sender,   /*  Queue for reply                  */
            "_CLIENT",                  /*  Name of event to send            */
            thread-> event-> body,      /*  Event body                       */
            thread-> event-> body_size, /*    and size                       */
            NULL, NULL, NULL,           /*  No response events               */
            0);                         /*  No timeout                       */
        tcb = (TCB *) child-> tcb;

        list_reset (&tcb-> reply);
        add_user_data (main_tcb, &tcb-> reply);
        tcb-> thread_type   = client_event;
        tcb-> main_req_type = main_tcb-> main_req_type;
        tcb-> host_name     = NULL;
        tcb-> ip_value      = NULL;
        if (tcb-> main_req_type == REQ_TYPE_HOST)
          {
            tcb-> ip_address = main_tcb-> ip_address;
            tcb-> ip_value   = mem_strdup (main_tcb-> ip_value);
            mem_strfree (&main_tcb-> ip_value);
          }
        else
          {
            tcb-> host_name = mem_strdup (main_tcb-> host_name);
            mem_strfree (&main_tcb-> host_name);
          }
      }
}
Exemplo n.º 5
0
MODULE terminate_the_thread (THREAD *thread)
{
    NS_REQUEST
        *next,
        *request;
    USER_DATA
        *next_data,
        *user_data;

    tcb = thread-> tcb;                 /*  Point to thread's context        */

    mem_strfree (&tcb-> ip_value);
    mem_strfree (&tcb-> host_name);

    if (tcb-> handle)
        close_socket (tcb-> handle);

    if (tcb-> query)
        mem_free (tcb-> query);

    /* Free stack of requests                                                */
    request = tcb-> stack.next;
    while ((void *)request != (void *)&tcb-> stack)
      {
        next = request-> next;
        rdns_request_free (request);
        request = next;
      }

    /* Free reply list                                                       */
    user_data = tcb-> reply.next;
    while ((void *)user_data != (void *)&tcb-> reply)
      {
        next_data = user_data-> next;
        mem_free (user_data);
        user_data = next_data;
      }
    if (tcb-> invalid_ns_tab)
        sym_delete_table (tcb-> invalid_ns_tab);

    if (tcb-> rr_result)
        mem_free (tcb-> rr_result);

    the_next_event = terminate_event;
}
Exemplo n.º 6
0
MODULE get_message_put_file (THREAD *thread)
{
    tcb = thread-> tcb;                 /*  Point to thread's context        */

    mem_strfree (&tcb-> file_name);
    mem_strfree (&tcb-> pipe);
    exdr_read (thread-> event-> body, SMT_FTPD_PUTF,
               &tcb-> id,
               &tcb-> passive,
               &tcb-> file_type,
               &tcb-> file_name,
               &tcb-> file_offset,
               &tcb-> data_host,
               &tcb-> data_port,
               &tcb-> pipe);

    tcb-> transfer_type = PUT_FILE_MODE;
    if (tcb-> thread_type != passive_event)
        tcb-> reply_to = thread-> event-> sender;
}
Exemplo n.º 7
0
int 
heap_dispose (void)
{
    mem_strfree (&path);
    if (file_list)
      {
        free_dir_list (file_list);
        file_list = NULL;
        file_info = NULL;
      }

    return HEAP_OK;
}
Exemplo n.º 8
0
void
destroy_value (VALUE *value)
{
    if (value-> s)
        mem_strfree (& value-> s);
    if (value-> b)
      {
        mem_free (value-> b);
        value-> b = NULL;
      }
    if (value-> i)
      {
        if (value-> c-> destroy)
            value-> c-> destroy (value-> i);
        value-> c = NULL;
        value-> i = NULL;
      }
}
Exemplo n.º 9
0
MODULE lookup_host_in_cache (THREAD *thread)
{
    SYMBOL
        *symbol;
    long
        current_time;

    tcb = thread-> tcb;                 /*  Point to thread's context        */

    symbol = sym_lookup_symbol (cache_table, tcb-> cur_request-> host_name);
    if (symbol)
      {
        current_time = (long)time (NULL);
        if (symbol-> data               /*  Check Time to live               */
        && (   *(long *)symbol-> data == -1
            || *(long *)symbol-> data >= current_time))
          {
            if (symbol-> value)
              {
                mem_strfree (&tcb-> ip_value);
                tcb-> ip_value    = mem_strdup (symbol-> value);
                tcb-> ip_address  = inet_addr (tcb-> ip_value);
                if (dns_debug_mode)
                    coputs ("Found in cache");
                the_next_event    = found_event;
              }
            else
                the_next_event    = found_bad_event;
          }
        else
          {
            if (symbol-> data)          /*  Delete cache entry: expired time */
              {
                mem_free (symbol-> data);
                sym_delete_symbol (cache_table, symbol);
              }
            the_next_event = not_found_event;
          }
      }
    else
        the_next_event = not_found_event;
}
Exemplo n.º 10
0
MODULE lookup_ip_in_cache (THREAD *thread)
{
    SYMBOL
        *symbol;
    long
        current_time;

    tcb = thread-> tcb;                 /*  Point to thread's context        */

    the_next_event = not_found_event;
    for (symbol = cache_table-> symbols; symbol; symbol = symbol-> next)
      {
         if(symbol-> value
         && streq (symbol-> value, tcb-> cur_request-> host_address))
           {
             current_time = (long)time (NULL);
             if (symbol-> data          /*  Check Time to live               */
             && (   *(long *)symbol-> data == -1
                 || *(long *)symbol-> data >= current_time))
               {
                 if (strneq (symbol-> name, symbol-> value))
                   {
                     mem_strfree (&tcb-> host_name);
                     tcb-> host_name = mem_strdup (symbol-> name);
                     if (dns_debug_mode)
                         coputs ("Found in cache");
                     the_next_event = found_event;
                   }
                 else                   /*  Found bad result in cache        */
                     the_next_event = found_bad_event;
               }
             else
             if (symbol-> data)         /*  Delete cache entry: expired time */
               {
                 mem_free (symbol-> data);
                 sym_delete_symbol (cache_table, symbol);
               }
             break;
           }
      }
}
Exemplo n.º 11
0
MODULE reply_to_wsx_request (THREAD *thread)
{
    DESCR
        symbols;                        /*  Symbol descriptor                */
    SYMTAB
        *envtab;                        /*  Environment symbols              */
    SYMBOL
        *script_path,                   /*  Symbols passed from core         */
        *script_name,
        *redirect_to;
    char
        *redirect;                      /*  URL to redirect to               */
    
    symbols.size = request-> symbols_size;
    symbols.data = request-> symbols_data;
    envtab = descr2symb (&symbols);
    script_path = sym_lookup_symbol (envtab, "SCRIPT_PATH");
    script_name = sym_lookup_symbol (envtab, "SCRIPT_NAME");
    if (script_path) {
        redirect = strprintf ("redirect:%s", script_path-> value);
        redirect_to = sym_lookup_symbol (config, redirect);
        if (!redirect_to && *script_path-> value == '/') {
            redirect = strprintf ("redirect:%s", script_path-> value + 1);
            redirect_to = sym_lookup_symbol (config, redirect);
        }    
    }
    if (redirect_to) {
        redirect = strconvchs (redirect_to-> value, '$',
                               script_name? script_name-> value + 1: "");
        send_wsx_redirect (&thread-> event-> sender, redirect);
        mem_strfree (&redirect);
    }
    sym_delete_table (envtab);

    /*  We're finished with the request structure - deallocate it            */
    free_smt_wsx_request (&request);
}
Exemplo n.º 12
0
Arquivo: sflmail.c Projeto: KubaO/gsl
int smtp_send_mail_ex (
   SMTP *smtp)
{
   FILE
      *fpin;
   int
       iCnt;
   sock_t
       socket_handle;
   char
       message_boundary [256],
       strOut           [514],
       strFile          [256],
       strUUEFile       [256],
       buffer           [BUFFER_SIZE + 1],
      *charset,
      *nb_bit,
      *data,
      *p_buffer,
      *strRcptUserIds;
   Bool
       old_ip_nonblock = ip_nonblock;
   int
       rcptUserIdsLen;
  long
      current_date,
      current_time,
      out_size,
      in_size;
  char
     *quoted_subject = NULL,
     *in_buf,
     *out_buf;

   /* Check required parameters                                              */
   if (smtp == NULL)
       return (SMTP_ERROR_CONNECT);
   if (smtp->strDestUserIds == NULL)
       return (SMTP_ERROR_MISSING_DESTINATION);
   if (smtp->strSubject == NULL)
       return (SMTP_ERROR_MISSING_SUBJECT);
   if (smtp->strSmtpServer == NULL)
       return (SMTP_ERROR_MISSING_SERVER_NAME);

   /*  Make sure we block on socket accesses                                 */
   ip_nonblock = FALSE;
   sock_init ();

   /* Open up the SMTP port (25 most of the time). */

   if (smtp-> connect_retry_cnt < 1)
       smtp-> connect_retry_cnt = 3;

   nb_bit = "7";

   if (smtp-> strCharSet == NULL 
   || *smtp-> strCharSet == '\0')
       charset = "US-ASCII";
   else
     {
       charset = smtp-> strCharSet;
       nb_bit = "8";
       if (smtp-> strSubject)
         {
           if (lexcmp (charset, "iso-2022-jp") == 0
           ||  lexcmp (charset, "shift_jis")   == 0
           ||  lexcmp (charset, "utf-8")       == 0) {
               quoted_subject = encode_mimeb_string (NULL, 0,
                                                  (byte *) smtp->strSubject, charset);
           }
           else
               quoted_subject = encode_quoted_string (NULL, 0,
                                                  (byte *) smtp->strSubject, charset);
         }
     }
   socket_handle = connect_socket (smtp-> strSmtpServer,
                                   "smtp", "tcp", NULL,
                                   smtp-> connect_retry_cnt,
                                   smtp-> retry_wait_time);

   if (socket_handle == INVALID_SOCKET
   ||  getreply (socket_handle, smtp) > SMTP_SERVER_ERROR)
     {
       mem_strfree  (&quoted_subject);
       sock_term ();
       return (SMTP_ERROR_CONNECT);
     }

   /* Format a SMTP meassage header.                                         */
   /* Just say hello to the mail server.                                     */
   xstrcpy (strOut, "HELO ", get_hostname (), "\r\n", NULL);
   send_data (socket_handle, strOut);
   if (getreply (socket_handle, smtp) > SMTP_SERVER_ERROR)
     {
       CLEAN_SEND_MAIL;
       return (SMTP_ERROR_INIT);
     }
   /* Tell the mail server who the message is from. */
   xstrcpy (strOut, "MAIL FROM:<", smtp-> strSenderUserId, ">\r\n", NULL);
   send_data (socket_handle, strOut);
   if (getreply (socket_handle, smtp) > SMTP_SERVER_ERROR)
     {
       CLEAN_SEND_MAIL;
       return (SMTP_ERROR_INVALID_SENDER);
     }
   rcptUserIdsLen = 0;
   if (smtp-> strDestUserIds)
       rcptUserIdsLen += strlen (smtp->strDestUserIds) + 1;
   if (smtp-> strCcUserIds)
       rcptUserIdsLen += strlen (smtp->strCcUserIds)   + 1;
   if (smtp-> strBccUserIds)
       rcptUserIdsLen += strlen (smtp->strBccUserIds)  + 1;

   strRcptUserIds = (char *) mem_alloc (rcptUserIdsLen);
   p_buffer = strRcptUserIds;
   data = smtp-> strDestUserIds;
   while (*data)
       *p_buffer++ = *data++;
   if (smtp-> strCcUserIds)
     {
       *p_buffer++ = ';';
       data = smtp-> strCcUserIds;
       while (*data)
           *p_buffer++ = *data++;
     }
   if (smtp-> strBccUserIds)
     {
       *p_buffer++ = ';';
       data = smtp-> strBccUserIds;
       while (*data)
           *p_buffer++ = *data++;
     }
   *p_buffer = '\0';

   /* The following tells the mail server who to send it to.                 */
   iCnt = 0;
   if (*strRcptUserIds) {
       FOREVER
         {
            getstrfld (strRcptUserIds, iCnt++, 0, ",;", buffer);
            if (*buffer)
             {
               xstrcpy (strOut, "RCPT TO:<", buffer, ">\r\n", NULL);
               send_data (socket_handle, strOut);
               if (getreply (socket_handle, smtp) > SMTP_SERVER_ERROR)
                 {
                   CLEAN_SEND_MAIL;
                   return (SMTP_ERROR_INVALID_RECEIPT_USER);
                 }
             }

           else
               break;
         }
    }
    mem_free (strRcptUserIds);

   /* Now give it the Subject and the message to send.                       */
   send_data (socket_handle, "DATA\r\n");
   if (getreply (socket_handle, smtp) > SMTP_SERVER_ERROR)
     {
       CLEAN_SEND_MAIL;
       return (SMTP_ERROR_INVALID_DATA);
     }

   /* Set the date and time of the message.                                  */
   get_date_time_now (&current_date, &current_time);
   xstrcpy ( strOut, "Date: ", encode_mime_time (current_date, current_time),
             " \r\n", NULL );

   /* The following shows all who it was sent to. */
   if ( smtp-> strFullDestUserIds && *smtp-> strFullDestUserIds )
    {
       replacechrswith (smtp-> strFullDestUserIds, ";", ',');
       xstrcat (strOut, "To: ", smtp-> strFullDestUserIds, "\r\n", NULL);
     }
   else
    {
       replacechrswith (smtp-> strDestUserIds, ";", ',');
       xstrcat (strOut, "To: ", smtp-> strDestUserIds, "\r\n", NULL);
    }

   /* Set up the Reply-To path. */
   if (!smtp-> strRetPathUserId || !*smtp-> strRetPathUserId)
       smtp-> strRetPathUserId = smtp-> strSenderUserId;

   if ( strstr( smtp-> strRetPathUserId, "<" ) != NULL &&
        strstr( smtp-> strRetPathUserId, ">" ) != NULL )
       xstrcat (strOut, "Reply-To:",  smtp-> strRetPathUserId, "\r\n", NULL);
   else
       xstrcat (strOut, "Reply-To:<", smtp-> strRetPathUserId, ">\r\n", NULL);

   if ( smtp-> strFullSenderUserId && *smtp-> strFullSenderUserId )
     {
       xstrcat (strOut, "Sender: ", smtp-> strFullSenderUserId, "\r\n", NULL);
       xstrcat (strOut, "From: ",   smtp-> strFullSenderUserId, "\r\n", NULL);
     }
   else
     {
       xstrcat (strOut, "Sender: ", smtp-> strSenderUserId, "\r\n", NULL);
       xstrcat (strOut, "From: ",   smtp-> strSenderUserId, "\r\n", NULL);
     }
   send_data (socket_handle, strOut);

   *strOut = '\0';

   /* Post any CC's. */
   if (smtp->strFullCcUserIds && *smtp->strFullCcUserIds)
     {
       replacechrswith (smtp->strFullCcUserIds, ";", ',');
       xstrcat (strOut, "Cc:", smtp->strFullCcUserIds, "\r\n", NULL );
     }
   else
   if (smtp->strCcUserIds && *smtp->strCcUserIds)
     {
       replacechrswith (smtp->strCcUserIds, ";", ',');
       xstrcat (strOut, "Cc:", smtp->strCcUserIds, "\r\n", NULL );
     }

   /* Post any BCC's. */
   if (smtp->strFullBccUserIds && *smtp->strFullBccUserIds)
     {
       replacechrswith (smtp->strFullBccUserIds, ";", ',');
       xstrcat (strOut, "Bcc:", smtp->strFullBccUserIds, "\r\n", NULL);
     }
   else
   if (smtp->strBccUserIds && *smtp->strBccUserIds)
     {
       replacechrswith (smtp->strBccUserIds, ";", ',');
       xstrcat (strOut, "Bcc:", smtp->strBccUserIds, "\r\n", NULL);
     }
   /* Post any Return-Receipt-To. */
   if (smtp->strRrcpUserId && *smtp->strRrcpUserId)
       xstrcat (strOut, "Return-Receipt-To:", smtp->strRrcpUserId, ">\r\n",
                NULL);

   if (smtp->strMailerName && *smtp->strMailerName)
       xstrcat (strOut, "X-Mailer: ", smtp->strMailerName, "\r\n", NULL);
   else
       strcat  (strOut, "X-Mailer: sflmail function\r\n");

   /* Set the mime version. */
   get_date_time_now (&current_date, &current_time);
   sprintf (message_boundary, "%s.%ld.%ld", MESSAGE_BOUNDARY,
            current_date, current_time);

   if ( smtp->strHtmlMessageBody && *smtp->strHtmlMessageBody )
       xstrcat (strOut, "MIME-Version: 1.0\r\n",
                "Content-Type: multipart/alternative; boundary=\"", 
	            message_boundary,"\"\r\n", NULL);
   else
       xstrcat (strOut, "MIME-Version: 1.0\r\n",
                "Content-Type: Multipart/Mixed; boundary=\"", 
	            message_boundary,"\"\r\n", NULL);

   send_data (socket_handle, strOut);

   *strOut = '\0';
   /* Write out any message comment included. */
   if (smtp->strMsgComment && *smtp->strMsgComment)
       xstrcpy (strOut, "Comments: ", smtp->strMsgComment, "\r\n", NULL);

   /* Send the subject and message body. */
   if (quoted_subject)
       xstrcat (strOut, "Subject: ", quoted_subject, "\r\n\r\n", NULL);
   else
       xstrcat (strOut, "Subject: ", smtp->strSubject, "\r\n\r\n", NULL);
   send_data (socket_handle, strOut);

   /* Keep rfc822 in mind with all the sections.                             */
    if (smtp->strMessageBody && *smtp->strMessageBody)
      {
        /* check if we got html/alternate files                               */
        if ( smtp->strHtmlMessageBody && *smtp->strHtmlMessageBody )
          {
           xstrcpy (strOut,
                     "\r\n\r\n--", message_boundary, "\r\n",
                     "Content-Type: text/html; charset=", charset, "\r\n",
                     "Content-Transfer-Encoding: 7BIT\r\n",
                     "Content-description: Body of message\r\n\r\n", NULL);
           send_data (socket_handle, strOut);
           send_body (socket_handle, smtp->strHtmlMessageBody);
           send_data (socket_handle, "\r\n");
           xstrcpy (strOut,
                    "\r\n--", message_boundary, "\r\n",
                    "Content-Type: text/plain; charset=", charset, "\r\n",
                    "Content-Transfer-Encoding: ", nb_bit, "BIT\r\n",
                    "Content-description: Body of message\r\n\r\n", NULL);
           send_data (socket_handle, strOut);
           send_body (socket_handle, smtp-> strMessageBody);
           send_data (socket_handle, "\r\n");

         }
       else
         {
           xstrcpy (strOut,
                    "\r\n--", message_boundary, "\r\n",
                    "Content-Type: text/plain; charset=", charset, "\r\n",
                    "Content-Transfer-Encoding: ", nb_bit, "BIT\r\n",
                    "Content-description: Body of message\r\n\r\n", NULL);
           send_data (socket_handle, strOut);
           send_body (socket_handle, smtp-> strMessageBody);
           send_data (socket_handle, "\r\n");
         }
     }
   /* Include any Text type files and Attach them to the message. */
   if (smtp->strTxtFiles && *smtp->strTxtFiles)
     {
       iCnt = 0;
       FOREVER
         {
           getstrfld (smtp->strTxtFiles, iCnt++, 0, ",;", strFile);
           strcrop (strskp (strFile));
           if (*strFile)
             {
               fpin = fopen (strFile, "rb");
               if (!fpin)
                 {
                   strcpy (smtp->strlast_smtp_message, strFile);
                     {
                       CLEAN_SEND_MAIL;
                       return (SMTP_ERROR_MISSING_ATTACH_FILE);
                     }
                 }

               xstrcpy (strOut, "\r\n--", message_boundary, "\r\n",
                       "Content-Type: text/plain; charset=", charset, "\r\n",
                       "Content-Transfer-Encoding: ", nb_bit, "BIT\r\n",
                       "Content-Disposition: attachment; filename=",
                        getfilename (strFile), "\r\n\r\n", NULL);
               send_data (socket_handle, strOut);
               while (fgets (buffer, BUFFER_SIZE, fpin))
                 {
                   if (*buffer == '.')
                       write_TCP (socket_handle, ".", 1);
                   send_data (socket_handle, buffer);
                 }
               fclose (fpin);
             }
           else
               break;
         }
     }
Exemplo n.º 13
0
SYMTAB *
ini_dyn_load (
    SYMTAB *load_symtab,
    const char *filename)
{
    FILE
        *inifile;
    SYMTAB
        *symtab,                        /*  Symbol table to populate         */
        *envtab;                        /*  Environment, as symbol table     */
    char
        *section = NULL,                /*  Filled as we scan through        */
        *keyword = NULL,                /*    the ini file                   */
        *value   = NULL,
        *fromptr,
        *toptr,
        *section_end;                   /*  Null byte at end of section      */

    ASSERT (filename);
    inifile = file_locate ("PATH", filename, NULL);

    if (load_symtab)                    /*  Use specified symbol table       */
        symtab = load_symtab;           /*    or create a new one            */
    else {
        symtab = sym_create_table ();
        if (symtab == NULL)
            return (NULL);              /*  Quit if insufficient memory      */
    }
    /*  Store control variables in symbol table                              */
    if (inifile || load_symtab == NULL) {
        sym_assume_symbol (symtab, "filename", filename);
        snprintf (iniline, sizeof (iniline), "%ld",
            timer_to_date (get_file_time (filename)));
        sym_assume_symbol (symtab, "filedate", iniline);
        snprintf (iniline, sizeof (iniline), "%ld",
            timer_to_time (get_file_time (filename)));
        sym_assume_symbol (symtab, "filetime", iniline);
    }
    if (!inifile)
        return (symtab);                /*  File not found; empty table      */

    /*  Now load the ini file, starting from the beginning                   */
    envtab = env2symb ();
    fseek (inifile, 0, SEEK_SET);
    FOREVER
      {
        if (ini_scan_section (inifile, &keyword, &value))
          {
            if (section)
              {
                section_end = strchr (section, '\0');
                ASSERT (section_end);
                xstrcat (section, ":", keyword, NULL);
                value = tok_subst (value, envtab);

                /*  Handle value in quotes                                   */
                if (*value == '"')
                  {
                    /*  Unescape value if necessary                          */
                    if (strchr (value, '\\'))
                      {
                        toptr = value;
                        for (fromptr = value; *fromptr; fromptr++)
                          {
                            if (*fromptr == '\\')
                              {
                                fromptr++;
                                if (*fromptr == 'n')
                                    *toptr++ = '\n';
                                else
                                    *toptr++ = *fromptr;
                              }
                            else
                                *toptr++ = *fromptr;
                          }
                        *toptr = '\0';
                      }
                    strlast (value) = '\0'; 
                    sym_assume_symbol (symtab, section, value + 1);
                  }
                else
                    sym_assume_symbol (symtab, section, value);

                mem_strfree (&value);
                *section_end = '\0';
              }
          }
        else
        if (keyword)                    /*  Found new section                */
          {
            section = keyword;
            sym_assume_symbol (symtab, section, "");
          }
        else
            break;
      }
    file_close (inifile);
    sym_delete_table (envtab);
    sym_sort_table (symtab, NULL);      /*  Sort table by symbol name        */
    return (symtab);
}