config_file.c
上传用户:tjfeida
上传日期:2013-03-10
资源大小:1917k
文件大小:40k
源码类别:

Ftp客户端

开发平台:

Visual C++

  1. /*****************************************************************************/
  2. /*  config_file.c - config file routines                                     */
  3. /*  Copyright (C) 1998-2002 Brian Masney <masneyb@gftp.org>                  */
  4. /*                                                                           */
  5. /*  This program is free software; you can redistribute it and/or modify     */
  6. /*  it under the terms of the GNU General Public License as published by     */
  7. /*  the Free Software Foundation; either version 2 of the License, or        */
  8. /*  (at your option) any later version.                                      */
  9. /*                                                                           */
  10. /*  This program is distributed in the hope that it will be useful,          */
  11. /*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  12. /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  13. /*  GNU General Public License for more details.                             */
  14. /*                                                                           */
  15. /*  You should have received a copy of the GNU General Public License        */
  16. /*  along with this program; if not, write to the Free Software              */
  17. /*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
  18. /*****************************************************************************/
  19. #include "gftp.h"
  20. static const char cvsid[] = "$Id: config_file.c,v 1.11 2002/12/04 02:35:44 masneyb Exp $";
  21. static void write_comment  ( FILE * fd, 
  22.   const char *comment );
  23. static int parse_args  ( char *str, 
  24.   int numargs, 
  25.   int lineno, 
  26.   char **first, 
  27.   ... );
  28. gftp_config_vars config_file_vars[] = 
  29. {
  30.   {"", N_("General"), (void *) 0x1, CONFIG_NOTEBOOK, "", NULL, GFTP_PORT_GTK},
  31.   {"", "", (void *) 0x1, CONFIG_TABLE, "", NULL, GFTP_PORT_GTK},
  32.   {"email", N_("Email address:"), &emailaddr, CONFIG_CHARTEXT, 
  33. N_("Enter your email address here"), NULL, GFTP_PORT_ALL},
  34.   {"view_program", N_("View program:"), &view_program, CONFIG_CHARTEXT,
  35. N_("The default program used to view files. If this is blank, the internal file viewer will be used"), NULL, GFTP_PORT_ALL},
  36.   {"edit_program", N_("Edit program:"), &edit_program, CONFIG_CHARTEXT,
  37. N_("The default program used to edit files."), NULL, GFTP_PORT_GTK},
  38.   {"startup_directory", N_("Startup Directory:"), &startup_directory, CONFIG_CHARTEXT,
  39.         N_("The default directory gFTP will go to on startup"), NULL, GFTP_PORT_ALL},
  40.   {"max_log_window_size", N_("Max Log Window Size:"), &max_log_window_size, CONFIG_UINTTEXT,
  41.         N_("The maximum size of the log window in bytes for the GTK+ port"), NULL, GFTP_PORT_GTK},
  42.   {"", "", (void *) 0x1, CONFIG_TABLE, "", NULL, GFTP_PORT_GTK},
  43.   {"append_transfers", N_("Append file transfers"), &append_file_transfers,
  44.         CONFIG_CHECKBOX,
  45.         N_("Append new file transfers onto existing ones"), NULL, GFTP_PORT_GTK},
  46.   {"one_transfer", N_("Do one transfer at a time"),  &do_one_transfer_at_a_time, CONFIG_CHECKBOX, 
  47. N_("Do only one transfer at a time?"), NULL, GFTP_PORT_GTK}, 
  48.   {"overwrite_default", N_("Overwrite by Default"), &overwrite_by_default, CONFIG_CHECKBOX,
  49.         N_("Overwrite files by default or set to resume file transfers"), NULL, GFTP_PORT_GTK},
  50.   {"refresh_files", N_("Refresh after each file transfer"), &refresh_files, CONFIG_CHECKBOX, 
  51. N_("Refresh the listbox after each file is transfered"), NULL, GFTP_PORT_GTK},
  52.   {"sort_dirs_first", N_("Sort directories first"), &sort_dirs_first, CONFIG_CHECKBOX, 
  53. N_("Put the directories first then the files"), NULL, GFTP_PORT_ALL},
  54.   {"start_transfers", N_("Start file transfers"), &start_file_transfers, CONFIG_CHECKBOX, 
  55. N_("Automatically start the file transfers when they get queued?"), NULL, GFTP_PORT_GTK},
  56.   {"show_hidden_files", N_("Show hidden files"), &show_hidden_files, CONFIG_CHECKBOX, 
  57. N_("Show hidden files in the listboxes"), NULL, GFTP_PORT_ALL},
  58.   
  59.   {"", N_("Network"), (void *) 0x1, CONFIG_NOTEBOOK, "", NULL, GFTP_PORT_GTK},
  60.   {"", "", (void *) 0x1, CONFIG_TABLE, "", NULL, GFTP_PORT_GTK},
  61.   {"network_timeout", N_("Network timeout:"), &network_timeout, CONFIG_INTTEXT, 
  62. N_("The timeout waiting for network input/output. This is NOT an idle timeout."), NULL, GFTP_PORT_ALL},
  63.   {"retries", N_("Connect retries:"), &retries, CONFIG_INTTEXT, 
  64. N_("The number of auto-retries to do. Set this to 0 to retry indefinately"), NULL, GFTP_PORT_ALL},
  65.   {"sleep_time", N_("Retry sleep time:"), &sleep_time, CONFIG_INTTEXT, 
  66. N_("The number of seconds to wait between retries"), NULL, GFTP_PORT_ALL},
  67.   {"maxkbs", N_("Max KB/S:"), &maxkbs, CONFIG_FLOATTEXT, 
  68. N_("The maximum KB/s a file transfer can get. (Set to 0 to disable)"), NULL, GFTP_PORT_ALL},
  69.   {"", N_("Default Protocol"), (void *) 0x1, CONFIG_COMBO, "DP", NULL, GFTP_PORT_GTK},
  70.   {"default_protocol", N_("Default Protocol"), &default_protocol, 
  71.         CONFIG_CHARTEXT, N_("This specifies the default protocol to use"), NULL, 0},
  72.   {"", N_("FTP"), (void *) 0x1, CONFIG_NOTEBOOK, "", NULL, GFTP_PORT_GTK},
  73.   {"", "", (void *) 0x1, CONFIG_TABLE, "", NULL, GFTP_PORT_GTK},
  74.   {"firewall_host", N_("Proxy hostname:"), &firewall_host, CONFIG_CHARTEXT,
  75. N_("Firewall hostname"), NULL, GFTP_PORT_ALL},
  76.   {"firewall_port", N_("Proxy port:"), &firewall_port, CONFIG_INTTEXT,
  77. N_("Port to connect to on the firewall"), NULL, GFTP_PORT_ALL},
  78.   {"firewall_username", N_("Proxy username:"), &firewall_username,
  79. CONFIG_CHARTEXT, N_("Your firewall username"), NULL, GFTP_PORT_ALL},
  80.   {"firewall_password", N_("Proxy password:"), &firewall_password, 
  81. CONFIG_CHARPASS, N_("Your firewall password"), NULL, GFTP_PORT_ALL},
  82.   {"firewall_account", N_("Proxy account:"), &firewall_account, CONFIG_CHARTEXT, 
  83. N_("Your firewall account (optional)"), NULL, GFTP_PORT_ALL},
  84.   {"", "", (void *) 0x1, CONFIG_TABLE, "", NULL, GFTP_PORT_GTK},
  85.   {"passive_transfer", N_("Passive file transfers"), &passive_transfer, CONFIG_CHECKBOX, 
  86. N_("Send PASV command or PORT command for data transfers"), NULL, GFTP_PORT_ALL},
  87.   {"resolve_symlinks", N_("Resolve Remote Symlinks (LIST -L)"), &resolve_symlinks, CONFIG_CHECKBOX, 
  88. N_("If you disable this feature, then gFTP will only send LIST to the remote server instead of LIST -L"), NULL, GFTP_PORT_ALL},
  89.   {"", "", (void *) 0x1, CONFIG_TABLE, "", NULL, GFTP_PORT_GTK},
  90.   {"", N_("Proxy server type"), (void *) 0x1, CONFIG_COMBO, "PS", NULL, GFTP_PORT_GTK},
  91.   {"proxy_config", N_("Proxy config"), &proxy_config, CONFIG_TEXT,
  92. N_("This specifies how your proxy server expects us to log in"), NULL, GFTP_PORT_GTK},
  93.   {"", N_("%pu = proxy user"), (void *) 0x1, CONFIG_LABEL, "", NULL, 0},
  94.   {"", N_("%hu = host user"), (void *) 0x1, CONFIG_LABEL, "", NULL, 0},
  95.   {"", N_("%pp = proxy pass"), (void *) 0x1, CONFIG_LABEL, "", NULL, 0},
  96.   {"", N_("%hp = host pass"), (void *) 0x1, CONFIG_LABEL, "", NULL, 0},
  97.   {"", N_("%ph = proxy host"), (void *) 0x1, CONFIG_LABEL, "", NULL, 0},
  98.   {"", N_("%hh = host"), (void *) 0x1, CONFIG_LABEL, "", NULL, 0},
  99.   {"", N_("%po = proxy port"), (void *) 0x1, CONFIG_LABEL, "", NULL, 0},
  100.   {"", N_("%ho = host port"), (void *) 0x1, CONFIG_LABEL, "", NULL, 0},
  101.   {"", N_("%pa = proxy account"), (void *) 0x1, CONFIG_LABEL, "", NULL, 0},
  102.   {"", N_("%ha = host account"), (void *) 0x1, CONFIG_LABEL, "", NULL, 0},
  103.   {"", N_("HTTP"), (void *) 0x1, CONFIG_NOTEBOOK, "", NULL, GFTP_PORT_GTK},
  104.   {"", "", (void *) 0x1, CONFIG_TABLE, "", NULL, GFTP_PORT_GTK},
  105.   {"http_proxy_host", N_("Proxy hostname:"), &http_proxy_host, CONFIG_CHARTEXT,
  106. N_("Firewall hostname"), NULL, GFTP_PORT_ALL},
  107.   {"http_proxy_port", N_("Proxy port:"), &http_proxy_port, CONFIG_INTTEXT, 
  108. N_("Port to connect to on the firewall"), NULL, GFTP_PORT_ALL},
  109.   {"http_proxy_username", N_("Proxy username:"), &http_proxy_username, 
  110. CONFIG_CHARTEXT, N_("Your firewall username"), NULL, GFTP_PORT_ALL},
  111.   {"http_proxy_password", N_("Proxy password:"), &http_proxy_password, 
  112. CONFIG_CHARPASS, N_("Your firewall password"), NULL, GFTP_PORT_ALL},
  113.   {"", "", (void *) 0x1, CONFIG_TABLE, "", NULL, GFTP_PORT_GTK},
  114.   {"use_http11", N_("Use HTTP/1.1"), &use_http11, CONFIG_CHECKBOX,
  115. N_("Do you want to use HTTP/1.1 or HTTP/1.0"), NULL, GFTP_PORT_ALL},
  116.   {"", N_("SSH"), (void *) 0x1, CONFIG_NOTEBOOK, "", NULL, GFTP_PORT_GTK},
  117.   {"", "", (void *) 0x1, CONFIG_TABLE, "", NULL, GFTP_PORT_GTK},
  118.   {"ssh_prog_name", N_("SSH Prog Name:"), &ssh_prog_name, CONFIG_CHARTEXT,
  119. N_("The path to the SSH executable"), NULL, GFTP_PORT_ALL},
  120.   {"ssh_extra_params", N_("SSH Extra Params:"), &ssh_extra_params, 
  121.         CONFIG_CHARTEXT, N_("Extra parameters to pass to the SSH program"), NULL, GFTP_PORT_ALL},
  122.   {"ssh1_sftp_path", N_("SSH sftpserv path:"), &ssh1_sftp_path,
  123. CONFIG_CHARTEXT, N_("Default remote SSH sftpserv path"), NULL, GFTP_PORT_ALL},
  124.   {"ssh2_sftp_path", N_("SSH2 sftp-server path:"), &ssh2_sftp_path,
  125. CONFIG_CHARTEXT, N_("Default remote SSH2 sftp-server path"), NULL, GFTP_PORT_ALL},
  126.   {"", "", (void *) 0x1, CONFIG_TABLE, "", NULL, GFTP_PORT_GTK},
  127.   {"ssh_need_userpass", N_("Need SSH User/Pass"), &ssh_need_userpass, CONFIG_CHECKBOX, 
  128.         N_("Require a username/password for SSH connections"), NULL, GFTP_PORT_ALL},
  129.   {"ssh_use_askpass", N_("Use ssh-askpass util"), &ssh_use_askpass, CONFIG_CHECKBOX, 
  130.         N_("Use the ssh-askpass utility to grab the users password"), NULL, GFTP_PORT_GTK},
  131.   {"sshv2_use_sftp_subsys", N_("Use SSH2 SFTP subsys"), &sshv2_use_sftp_subsys, CONFIG_CHECKBOX, 
  132.         N_("Call ssh with the -s sftp flag. This is helpful because you won't have to know the remote path to the remote sftp-server"), NULL, GFTP_PORT_GTK},
  133.   {"enable_old_ssh", N_("Enable old SSH protocol"), &enable_old_ssh, CONFIG_CHECKBOX, 
  134.         N_("Enable the old SSH protocol. You will need to download the sftp server from http:///www.xbill.org/sftp"), NULL, GFTP_PORT_ALL},
  135.   {"list_dblclk_action", "", &listbox_dblclick_action, CONFIG_HIDEINT, 
  136. N_("This defines what will happen when you double click a file in the file listboxes. 0=View file 1=Edit file 2=Transfer file"), NULL, 0},
  137.   {"listbox_local_width", "", &listbox_local_width, CONFIG_HIDEINT, 
  138. N_("The default width of the local files listbox"), NULL, 0},
  139.   {"listbox_remote_width", "", &listbox_remote_width, CONFIG_HIDEINT,
  140. N_("The default width of the remote files listbox"), NULL, 0},
  141.   {"listbox_file_height", "", &listbox_file_height, CONFIG_HIDEINT,
  142. N_("The default height of the local/remote files listboxes"), NULL, 0},
  143.   {"transfer_height", "", &transfer_height, CONFIG_HIDEINT,
  144. N_("The default height of the transfer listbox"), NULL, 0},
  145.   {"log_height", "", &log_height, CONFIG_HIDEINT,
  146. N_("The default height of the logging window"), NULL, 0},
  147.   {"file_trans_column", "", &file_trans_column, CONFIG_HIDEINT,
  148. N_("The width of the filename column in the transfer window. Set this to 0 to have this column automagically resize."), NULL, 0},
  149.   {"local_sortcol", "", &local_sortcol, CONFIG_INTTEXT, 
  150. N_("The default column to sort by"), NULL, GFTP_PORT_TEXT},
  151.   {"local_sortasds", "", &local_sortasds, CONFIG_INTTEXT,
  152. N_("Sort ascending or descending"), NULL, GFTP_PORT_TEXT},
  153.   {"remote_sortcol", "", &remote_sortcol, CONFIG_INTTEXT,
  154. N_("The default column to sort by"), NULL, GFTP_PORT_TEXT},
  155.   {"remote_sortasds", "", &remote_sortasds, CONFIG_INTTEXT,
  156. N_("Sort ascending or descending"), NULL, GFTP_PORT_TEXT},
  157.   {"local_file_width", "", &local_columns[0], CONFIG_HIDEINT,
  158. N_("The width of the filename column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  159.   {"local_size_width", "", &local_columns[1], CONFIG_HIDEINT,
  160. N_("The width of the size column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  161.   {"local_user_width", "", &local_columns[2], CONFIG_HIDEINT,
  162. N_("The width of the user column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  163.   {"local_group_width", "", &local_columns[3], CONFIG_HIDEINT,
  164. N_("The width of the group column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  165.   {"local_date_width", "", &local_columns[4], CONFIG_HIDEINT,
  166. N_("The width of the date column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  167.   {"local_attribs_width", "", &local_columns[5], CONFIG_HIDEINT,
  168. N_("The width of the attribs column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  169.   {"remote_file_width", "", &remote_columns[0], CONFIG_HIDEINT,
  170. N_("The width of the filename column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  171.   {"remote_size_width", "", &remote_columns[1], CONFIG_HIDEINT,
  172. N_("The width of the size column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  173.   {"remote_user_width", "", &remote_columns[2], CONFIG_HIDEINT,
  174. N_("The width of the user column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  175.   {"remote_group_width", "", &remote_columns[3], CONFIG_HIDEINT,
  176. N_("The width of the group column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  177.   {"remote_date_width", "", &remote_columns[4], CONFIG_HIDEINT,
  178. N_("The width of the date column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  179.   {"remote_attribs_width", "", &remote_columns[5], CONFIG_HIDEINT,
  180. N_("The width of the attribs column in the file listboxes. Set this to 0 to have this column automagically resize. Set this to -1 to disable this column"), NULL, 0},
  181.   {"send_color", "", &send_color, CONFIG_COLOR,
  182.         N_("The color of the commands that are sent to the server"), NULL, 0},
  183.   {"recv_color", "", &recv_color, CONFIG_COLOR,
  184.         N_("The color of the commands that are received from the server"), NULL, 0},
  185.   {"error_color", "", &error_color, CONFIG_COLOR,
  186.         N_("The color of the error messages"), NULL, 0},
  187.   {"misc_color", "", &misc_color, CONFIG_COLOR,
  188.         N_("The color of the rest of the log messages"), NULL, 0},
  189.   {NULL, NULL, NULL, 0, "", NULL, 0}
  190. };
  191. void
  192. gftp_read_config_file (char **argv, int get_xpms)
  193. {
  194.   char *tempstr, *temp1str, *curpos, *endpos, buf[255], *str, *red, *green, 
  195.        *blue;
  196.   gftp_file_extensions * tempext;
  197.   gftp_bookmarks * newentry;
  198.   gftp_proxy_hosts * host;
  199.   unsigned int nums[4];
  200.   struct hostent *hent;
  201.   struct utsname unme;
  202.   gftp_color * color;
  203.   struct passwd *pw;
  204.   FILE *conffile;
  205.   uid_t my_uid;
  206.   gid_t my_gid;
  207.   int line, i;
  208.   size_t len;
  209.   void *ptr;
  210.   memset (&send_color, 0, sizeof (send_color));
  211.   memset (&recv_color, 0, sizeof (recv_color));
  212.   memset (&error_color, 0, sizeof (error_color));
  213.   memset (&misc_color, 0, sizeof (misc_color));
  214.   send_color.green = 0x8600;
  215.   recv_color.blue = 0xffff;
  216.   error_color.red = 0xffff;
  217.   misc_color.red = 0xffff;
  218.   line = 0;
  219.   bookmarks = g_malloc0 (sizeof (*bookmarks));
  220.   bookmarks->isfolder = 1;
  221.   bookmarks->path = g_malloc0 (1);
  222.   bookmarks_htable = g_hash_table_new (string_hash_function, string_hash_compare);
  223.   config_htable = g_hash_table_new (string_hash_function, string_hash_compare);
  224.   if ((tempstr = expand_path (CONFIG_FILE)) == NULL)
  225.     {
  226.       printf (_("gFTP Error: Bad config file name %sn"), CONFIG_FILE);
  227.       exit (0);
  228.     }
  229.   if (access (tempstr, F_OK) == -1)
  230.     {
  231.       temp1str = expand_path (BASE_CONF_DIR);
  232.       if (access (temp1str, F_OK) == -1)
  233. {
  234.   if (mkdir (temp1str, S_IRUSR | S_IWUSR | S_IXUSR) != 0)
  235.     {
  236.       printf (_("gFTP Error: Could not make directory %s: %sn"),
  237.       temp1str, g_strerror (errno));
  238.       exit (-1);
  239.     }
  240. }
  241.       g_free (temp1str);
  242.       temp1str = g_strdup_printf ("%s/gftprc", SHARE_DIR);
  243.       if (access (temp1str, F_OK) == -1)
  244. {
  245.   printf (_("gFTP Error: Cannot find master config file %sn"),
  246.   temp1str);
  247.   printf (_("Did you do a make install?n"));
  248.   exit (-1);
  249. }
  250.       copyfile (temp1str, tempstr);
  251.       g_free (temp1str);
  252.     }
  253.   if ((conffile = fopen (tempstr, "r")) == NULL)
  254.     {
  255.       printf (_("gFTP Error: Cannot open config file %s: %sn"), CONFIG_FILE,
  256.       g_strerror (errno));
  257.       exit (0);
  258.     }
  259.   g_free (tempstr);
  260.  
  261.   for (i = 0; config_file_vars[i].var != NULL; i++)
  262.     {
  263.       g_hash_table_insert (config_htable, config_file_vars[i].key, 
  264.                            GINT_TO_POINTER(i));
  265.     } 
  266.   while (fgets (buf, sizeof (buf), conffile))
  267.     {
  268.       len = strlen (buf);
  269.       if (buf[len - 1] == 'n')
  270. buf[--len] = '';
  271.       if (len && buf[len - 1] == 'r')
  272. buf[--len] = '';
  273.       line++;
  274.       if (*buf == '#' || *buf == '')
  275.         continue;
  276.       if ((curpos = strchr (buf, '=')) != NULL)
  277.         *curpos = '';
  278.       if ((ptr = g_hash_table_lookup (config_htable, buf)) != NULL)
  279.         {
  280.           i = GPOINTER_TO_INT(ptr);
  281.           curpos = buf + strlen (buf) + 1;
  282.           if (config_file_vars[i].type == CONFIG_CHARTEXT ||
  283.               config_file_vars[i].type == CONFIG_CHARPASS ||
  284.               config_file_vars[i].type == CONFIG_TEXT)
  285.             {
  286.               *(char **) config_file_vars[i].var = g_malloc (strlen (curpos) + 1);
  287.               strcpy (*(char **) config_file_vars[i].var, curpos);
  288.             }
  289.           else if (config_file_vars[i].type == CONFIG_FLOATTEXT)
  290.             *(double *) config_file_vars[i].var = strtod (curpos, NULL);
  291.           else if (config_file_vars[i].type == CONFIG_COLOR)
  292.             {
  293.               color = config_file_vars[i].var;
  294.               parse_args (curpos, 3, line, &red, &green, &blue);
  295.               color->red = strtol (red, NULL, 16);
  296.               color->green = strtol (green, NULL, 16);
  297.               color->blue = strtol (blue, NULL, 16);
  298.               g_free (red);
  299.               g_free (green);
  300.               g_free (blue);
  301.             }
  302.           else
  303.             *(int *) config_file_vars[i].var = strtol (curpos, NULL, 10);
  304. }
  305.       else if (strcmp (buf, "host") == 0)
  306. {
  307.           /* This is just here for compatibility with old versions of gftp */
  308.   curpos = buf + 5;
  309.   while (*curpos == '/')
  310.     curpos++;
  311.   newentry = g_malloc0 (sizeof (*newentry));
  312.   newentry->isfolder = 0;
  313.   parse_args (curpos, 8, line, &newentry->path, &newentry->hostname,
  314.       &temp1str, &newentry->remote_dir, &newentry->user,
  315.       &newentry->pass, &tempstr, &newentry->acct);
  316.   newentry->port = strtol (temp1str, NULL, 10);
  317.   g_free (temp1str);
  318.   newentry->save_password = *newentry->pass != '';
  319.   add_to_bookmark (newentry);
  320. }
  321.       else if (strcmp (buf, "dont_use_proxy") == 0)
  322. {
  323.   curpos = buf + 15;
  324.   host = g_malloc0 (sizeof (*host));
  325.   if ((tempstr = strchr (curpos, '/')) == NULL)
  326.     {
  327.       host->domain = g_malloc (strlen (curpos) + 1);
  328.       strcpy (host->domain, curpos);
  329.     }
  330.   else
  331.     {
  332.       *tempstr = '';
  333.       sscanf (curpos, "%u.%u.%u.%u", &nums[0], &nums[1], &nums[2],
  334.       &nums[3]);
  335.       host->ipv4_network_address =
  336. nums[0] << 24 | nums[1] << 16 | nums[2] << 8 | nums[3];
  337.       if (strchr (tempstr + 1, '.') == NULL)
  338. host->ipv4_netmask =
  339.     0xffffffff << (32 - strtol (tempstr + 1, NULL, 10));
  340.       else
  341. {
  342.   sscanf (tempstr + 1, "%u.%u.%u.%u", &nums[0], &nums[1],
  343.   &nums[2], &nums[3]);
  344.   host->ipv4_netmask =
  345.     nums[0] << 24 | nums[1] << 16 | nums[2] << 8 | nums[3];
  346. }
  347.     }
  348.   proxy_hosts = g_list_append (proxy_hosts, host);
  349. }
  350.       else if (strcmp (buf, "ext") == 0)
  351. {
  352.           if (get_xpms)
  353.             {
  354.       curpos = buf + 4;
  355.       tempext = g_malloc (sizeof (*tempext));
  356.       parse_args (curpos, 4, line, &tempext->ext, &tempext->filename,
  357.              &tempext->ascii_binary, &tempext->view_program);
  358.  
  359.       if ((tempstr = get_xpm_path (tempext->filename, 1)) != NULL)
  360.         g_free (tempstr);
  361.       tempext->stlen = strlen (tempext->ext);
  362.               registered_exts = g_list_append (registered_exts, tempext);
  363.             }
  364. }
  365.       else if (strcmp (buf, "localhistory") == 0)
  366. {
  367.   curpos = buf + 13;
  368.   str = g_malloc (strlen (curpos) + 1);
  369.   strcpy (str, curpos);
  370.   localhistory = g_list_append (localhistory, str);
  371.   localhistlen++;
  372. }
  373.       else if (strcmp (buf, "remotehistory") == 0)
  374. {
  375.   curpos = buf + 14;
  376.   str = g_malloc (strlen (curpos) + 1);
  377.   strcpy (str, curpos);
  378.   remotehistory = g_list_append (remotehistory, str);
  379.   remotehistlen++;
  380. }
  381.       else if (strcmp (buf, "hosthistory") == 0)
  382. {
  383.   curpos = buf + 12;
  384.   str = g_malloc (strlen (curpos) + 1);
  385.   strcpy (str, curpos);
  386.   host_history = g_list_append (host_history, str);
  387.   host_len++;
  388. }
  389.       else if (strcmp (buf, "porthistory") == 0)
  390. {
  391.   curpos = buf + 12;
  392.   str = g_malloc (strlen (curpos) + 1);
  393.   strcpy (str, curpos);
  394.   port_history = g_list_append (port_history, str);
  395.   port_len++;
  396. }
  397.       else if (strcmp (buf, "userhistory") == 0)
  398. {
  399.   curpos = buf + 12;
  400.   str = g_malloc (strlen (curpos) + 1);
  401.   strcpy (str, curpos);
  402.   user_history = g_list_append (user_history, str);
  403.   user_len++;
  404. }
  405.       else
  406. {
  407.   printf (_("gFTP Warning: Skipping line %d in config file: %sn"),
  408.                   line, buf);
  409. }
  410.     }
  411.   if (default_protocol == NULL)
  412.     {
  413.       default_protocol = g_malloc (4);
  414.       strcpy (default_protocol, "FTP");
  415.     }
  416.   if (!enable_old_ssh)
  417.     {
  418.       gftp_protocols[GFTP_SSH_NUM].name = NULL;
  419.       gftp_protocols[GFTP_SSH_NUM].init = NULL;
  420.       gftp_protocols[GFTP_SSH_NUM].url_prefix = NULL;
  421.       gftp_protocols[GFTP_SSH_NUM].shown = 0;
  422.     }
  423.   if ((tempstr = expand_path (LOG_FILE)) == NULL)
  424.     {
  425.       printf (_("gFTP Error: Bad log file name %sn"), LOG_FILE);
  426.       exit (0);
  427.     }
  428.   if ((logfd = fopen (tempstr, "w")) == NULL)
  429.     {
  430.       printf (_("gFTP Warning: Cannot open %s for writing: %sn"),
  431.               tempstr, g_strerror (errno));
  432.     }
  433.   g_free (tempstr);
  434.   gftp_read_bookmarks ();
  435.   if (ssh_extra_params != NULL)
  436.     {
  437.       num_ssh_extra_params = 0;
  438.       curpos = ssh_extra_params;
  439.       while ((endpos = strchr (curpos, ' ')) != NULL)
  440.         {
  441.           *endpos = '';
  442.           num_ssh_extra_params++;
  443.           ssh_extra_params_list = g_realloc (ssh_extra_params_list,
  444.                                              (num_ssh_extra_params + 1) * 
  445.                                              sizeof (char *));
  446.           ssh_extra_params_list[num_ssh_extra_params - 1] = g_strdup (curpos);
  447.           ssh_extra_params_list[num_ssh_extra_params] = NULL;
  448.           *endpos = ' ';
  449.           curpos = endpos + 1;
  450.         }
  451.       if (*curpos != '')
  452.         {
  453.           num_ssh_extra_params++;
  454.           ssh_extra_params_list = g_realloc (ssh_extra_params_list,
  455.                                              (num_ssh_extra_params + 1) * 
  456.                                              sizeof (char *));
  457.           ssh_extra_params_list[num_ssh_extra_params - 1] = g_strdup (curpos);
  458.           ssh_extra_params_list[num_ssh_extra_params] = NULL;
  459.         }
  460.     }
  461.   make_nonnull (&proxy_config);
  462.   make_nonnull (&firewall_host);
  463.   make_nonnull (&firewall_username);
  464.   make_nonnull (&firewall_password);
  465.   make_nonnull (&firewall_account);
  466.   make_nonnull (&http_proxy_host);
  467.   make_nonnull (&http_proxy_username);
  468.   make_nonnull (&http_proxy_password);
  469.   make_nonnull (&view_program);
  470.   make_nonnull (&edit_program);
  471.   my_uid = geteuid ();
  472.   my_gid = getegid ();
  473.   pw = getpwuid (my_uid);
  474.   if (emailaddr == NULL || *emailaddr == '')
  475.     {
  476.       /* If there is no email address specified, then we'll just use the
  477.          currentuser@currenthost */
  478.       if (emailaddr)
  479.         g_free (emailaddr);
  480.       uname (&unme);
  481.       hent = gethostbyname (unme.nodename);
  482.       if (strchr (unme.nodename, '.') == NULL && hent != NULL)
  483.         emailaddr = g_strconcat (pw->pw_name, "@", hent->h_name, NULL);
  484.       else
  485.         emailaddr = g_strconcat (pw->pw_name, "@", unme.nodename, NULL);
  486.       gftp_write_config_file ();
  487.     }
  488. }
  489. void
  490. gftp_read_bookmarks (void)
  491. {
  492.   char *tempstr, *temp1str, buf[255], *curpos;
  493.   gftp_bookmarks *newentry;
  494.   FILE *bmfile;
  495.   size_t len;
  496.   int line;
  497.   if ((tempstr = expand_path (BOOKMARKS_FILE)) == NULL)
  498.     {
  499.       printf (_("gFTP Error: Bad bookmarks file name %sn"), BOOKMARKS_FILE);
  500.       exit (0);
  501.     }
  502.   if (access (tempstr, F_OK) == -1)
  503.     {
  504.       temp1str = g_strdup_printf ("%s/bookmarks", SHARE_DIR);
  505.       if (access (temp1str, F_OK) == -1)
  506. {
  507.   printf (_("Warning: Cannot find master bookmark file %sn"),
  508.   temp1str);
  509.   g_free (temp1str);
  510.   return;
  511. }
  512.       copyfile (temp1str, tempstr);
  513.       g_free (temp1str);
  514.     }
  515.   if ((bmfile = fopen (tempstr, "r")) == NULL)
  516.     {
  517.       printf (_("gFTP Error: Cannot open bookmarks file %s: %sn"), tempstr,
  518.       g_strerror (errno));
  519.       exit (0);
  520.     }
  521.   g_free (tempstr);
  522.   line = 0;
  523.   newentry = NULL;
  524.   while (fgets (buf, sizeof (buf), bmfile))
  525.     {
  526.      len = strlen (buf);
  527.       if (buf[len - 1] == 'n')
  528. buf[--len] = '';
  529.       if (len && buf[len - 1] == 'r')
  530. buf[--len] = '';
  531.       line++;
  532.       if (*buf == '[')
  533. {
  534.   newentry = g_malloc0 (sizeof (*newentry));
  535.   for (; buf[len - 1] == ' ' || buf[len - 1] == ']'; buf[--len] = '');
  536.   newentry->path = g_malloc (len);
  537.   strcpy (newentry->path, buf + 1);
  538.   newentry->isfolder = 0;
  539.   add_to_bookmark (newentry);
  540. }
  541.       else if (strncmp (buf, "hostname", 8) == 0 && newentry)
  542. {
  543.   curpos = buf + 9;
  544.   if (newentry->hostname)
  545.     g_free (newentry->hostname);
  546.   newentry->hostname = g_malloc (strlen (curpos) + 1);
  547.   strcpy (newentry->hostname, curpos);
  548. }
  549.       else if (strncmp (buf, "port", 4) == 0 && newentry)
  550. newentry->port = strtol (buf + 5, NULL, 10);
  551.       else if (strncmp (buf, "protocol", 8) == 0 && newentry)
  552. {
  553.   curpos = buf + 9;
  554.   if (newentry->protocol)
  555.     g_free (newentry->protocol);
  556.   newentry->protocol = g_malloc (strlen (curpos) + 1);
  557.   strcpy (newentry->protocol, curpos);
  558. }
  559.       else if (strncmp (buf, "remote directory", 16) == 0 && newentry)
  560. {
  561.   curpos = buf + 17;
  562.   if (newentry->remote_dir)
  563.     g_free (newentry->remote_dir);
  564.   newentry->remote_dir = g_malloc (strlen (curpos) + 1);
  565.   strcpy (newentry->remote_dir, curpos);
  566. }
  567.       else if (strncmp (buf, "local directory", 15) == 0 && newentry)
  568. {
  569.   curpos = buf + 16;
  570.   if (newentry->local_dir)
  571.     g_free (newentry->local_dir);
  572.   newentry->local_dir = g_malloc (strlen (curpos) + 1);
  573.   strcpy (newentry->local_dir, curpos);
  574. }
  575.       else if (strncmp (buf, "username", 8) == 0 && newentry)
  576. {
  577.   curpos = buf + 9;
  578.   if (newentry->user)
  579.     g_free (newentry->user);
  580.   newentry->user = g_malloc (strlen (curpos) + 1);
  581.   strcpy (newentry->user, curpos);
  582. }
  583.       else if (strncmp (buf, "password", 8) == 0 && newentry)
  584. {
  585.   curpos = buf + 9;
  586.   if (newentry->pass)
  587.     g_free (newentry->pass);
  588.   newentry->pass = g_malloc (strlen (curpos) + 1);
  589.   strcpy (newentry->pass, curpos);
  590.   newentry->save_password = *newentry->pass != '';
  591. }
  592.       else if (strncmp (buf, "account", 7) == 0 && newentry)
  593. {
  594.   curpos = buf + 8;
  595.   if (newentry->acct)
  596.     g_free (newentry->acct);
  597.   newentry->acct = g_malloc (strlen (curpos) + 1);
  598.   strcpy (newentry->acct, curpos);
  599. }
  600.       else if (strncmp (buf, "sftpserv_path", 13) == 0 && newentry)
  601.         {
  602.           curpos = buf + 14;
  603.           if (newentry->sftpserv_path)
  604.             g_free (newentry->sftpserv_path);
  605.           newentry->sftpserv_path = g_malloc (strlen (curpos) + 1);
  606.           strcpy (newentry->sftpserv_path, curpos);
  607.         }
  608.       else if (*buf != '#' && *buf != '')
  609. printf (_("gFTP Warning: Skipping line %d in bookmarks file: %sn"),
  610. line, buf);
  611.     }
  612. }
  613. void
  614. add_to_bookmark (gftp_bookmarks * newentry)
  615. {
  616.   gftp_bookmarks *preventry, *folderentry, *endentry;
  617.   char *curpos;
  618.   if (!newentry->protocol)
  619.     {
  620.       newentry->protocol = g_malloc (4);
  621.       strcpy (newentry->protocol, "FTP");
  622.     }
  623.   /* We have to create the folders. For example, if we have 
  624.      Debian Sites/Debian, we have to create a Debian Sites entry */
  625.   preventry = bookmarks;
  626.   if (preventry->children != NULL)
  627.     {
  628.       endentry = preventry->children;
  629.       while (endentry->next != NULL)
  630. endentry = endentry->next;
  631.     }
  632.   else
  633.     endentry = NULL;
  634.   curpos = newentry->path;
  635.   while ((curpos = strchr (curpos, '/')) != NULL)
  636.     {
  637.       *curpos = '';
  638.       /* See if we already made this folder */
  639.       if ((folderentry = (gftp_bookmarks *)
  640.    g_hash_table_lookup (bookmarks_htable, newentry->path)) == NULL)
  641. {
  642.   /* Allocate the individual folder. We have to do this for the edit 
  643.      bookmarks feature */
  644.   folderentry = g_malloc0 (sizeof (*folderentry));
  645.   folderentry->path = g_malloc (strlen (newentry->path) + 1);
  646.   strcpy (folderentry->path, newentry->path);
  647.   folderentry->prev = preventry;
  648.   folderentry->isfolder = 1;
  649.   g_hash_table_insert (bookmarks_htable, folderentry->path,
  650.        folderentry);
  651.   if (preventry->children == NULL)
  652.     preventry->children = folderentry;
  653.   else
  654.     endentry->next = folderentry;
  655.   preventry = folderentry;
  656.   endentry = NULL;
  657. }
  658.       else
  659. {
  660.   preventry = folderentry;
  661.   if (preventry->children != NULL)
  662.     {
  663.       endentry = preventry->children;
  664.       while (endentry->next != NULL)
  665. endentry = endentry->next;
  666.     }
  667.   else
  668.     endentry = NULL;
  669. }
  670.       *curpos = '/';
  671.       curpos++;
  672.     }
  673.   /* Get the parent node */
  674.   if ((curpos = strrchr (newentry->path, '/')) == NULL)
  675.     preventry = bookmarks;
  676.   else
  677.     {
  678.       *curpos = '';
  679.       preventry = (gftp_bookmarks *)
  680. g_hash_table_lookup (bookmarks_htable, newentry->path);
  681.       *curpos = '/';
  682.     }
  683.   if (preventry->children != NULL)
  684.     {
  685.       endentry = preventry->children;
  686.       while (endentry->next != NULL)
  687. endentry = endentry->next;
  688.       endentry->next = newentry;
  689.     }
  690.   else
  691.     preventry->children = newentry;
  692.   newentry->prev = preventry;
  693.   newentry->next = NULL;
  694.   g_hash_table_insert (bookmarks_htable, newentry->path, newentry);
  695. }
  696. void
  697. gftp_write_config_file (void)
  698. {
  699.   char *hdr, *proxyhdr, *exthdr, *histhdr;
  700.   gftp_file_extensions *tempext;
  701.   gftp_proxy_hosts *hosts;
  702.   gftp_color *color;
  703.   GList *templist;
  704.   FILE *conffile;
  705.   char *tempstr;
  706.   int pos;
  707.   hdr = N_("Config file for gFTP. Copyright (C) 1998-2002 Brian Masney <masneyb@gftp.org>. Warning: Any comments that you add to this file WILL be overwritten. If a entry has a (*) in it's comment, you can't change it inside gFTP");
  708.   proxyhdr = N_("This section specifies which hosts are on the local subnet and won't need to go out the proxy server (if available). Syntax: dont_use_proxy=.domain or dont_use_proxy=network number/netmask");
  709.   exthdr = N_("ext=file extenstion:XPM file:Ascii or Binary (A or B):viewer program. Note: All arguments except the file extension are optional");
  710.   histhdr = N_("This section contains the data that is in the history");
  711.   if ((tempstr = expand_path (CONFIG_FILE)) == NULL)
  712.     {
  713.       printf (_("gFTP Error: Bad config file name %sn"), CONFIG_FILE);
  714.       exit (0);
  715.     }
  716.   if ((conffile = fopen (tempstr, "w+")) == NULL)
  717.     {
  718.       printf (_("gFTP Error: Cannot open config file %s: %sn"), CONFIG_FILE,
  719.       g_strerror (errno));
  720.       exit (0);
  721.     }
  722.   g_free (tempstr);
  723.   write_comment (conffile, _(hdr));
  724.   fwrite ("n", 1, 1, conffile);
  725.   for (pos = 0; config_file_vars[pos].var != NULL; pos++)
  726.     {
  727.       if (config_file_vars[pos].type == CONFIG_CHARTEXT ||
  728.           config_file_vars[pos].type == CONFIG_CHARPASS ||
  729.           config_file_vars[pos].type == CONFIG_TEXT)
  730.         {
  731.           if (*config_file_vars[pos].comment != '')
  732.             write_comment (conffile, _(config_file_vars[pos].comment));
  733.   fprintf (conffile, "%s=%snn", config_file_vars[pos].key,
  734.       *(char **) config_file_vars[pos].var == NULL ? "" :
  735.                    *(char **) config_file_vars[pos].var);
  736.         }
  737.       else if (config_file_vars[pos].type == CONFIG_FLOATTEXT)
  738.         {
  739.           if (*config_file_vars[pos].comment != '')
  740.             write_comment (conffile, _(config_file_vars[pos].comment));
  741.   fprintf (conffile, "%s=%.2fnn", config_file_vars[pos].key,
  742.                    *(double *) config_file_vars[pos].var);
  743.         }
  744.       else if (config_file_vars[pos].type == CONFIG_INTTEXT ||
  745.                config_file_vars[pos].type == CONFIG_UINTTEXT ||
  746.                config_file_vars[pos].type == CONFIG_CHECKBOX ||
  747.                config_file_vars[pos].type == CONFIG_HIDEINT)
  748.         {
  749.           if (*config_file_vars[pos].comment != '')
  750.             write_comment (conffile, _(config_file_vars[pos].comment));
  751.   fprintf (conffile, "%s=%dnn", config_file_vars[pos].key,
  752.                    *(int *) config_file_vars[pos].var);
  753.         }
  754.       else if (config_file_vars[pos].type == CONFIG_COLOR)
  755.         {
  756.           if (*config_file_vars[pos].comment != '')
  757.             write_comment (conffile, _(config_file_vars[pos].comment));
  758.           color = config_file_vars[pos].var;
  759.           fprintf (conffile, "%s=%x:%x:%xnn", config_file_vars[pos].key,
  760.                    color->red, color->green, color->blue);
  761.         }
  762.     }
  763.   write_comment (conffile, _(proxyhdr));
  764.   templist = proxy_hosts;
  765.   while (templist != NULL)
  766.     {
  767.       hosts = templist->data;
  768.       if (hosts->domain)
  769. fprintf (conffile, "dont_use_proxy=%sn", hosts->domain);
  770.       else
  771. fprintf (conffile, "dont_use_proxy=%d.%d.%d.%d/%d.%d.%d.%dn",
  772.  hosts->ipv4_network_address >> 24 & 0xff,
  773.  hosts->ipv4_network_address >> 16 & 0xff,
  774.  hosts->ipv4_network_address >> 8 & 0xff,
  775.  hosts->ipv4_network_address & 0xff,
  776.  hosts->ipv4_netmask >> 24 & 0xff,
  777.  hosts->ipv4_netmask >> 16 & 0xff,
  778.  hosts->ipv4_netmask >> 8 & 0xff, hosts->ipv4_netmask & 0xff);
  779.       templist = templist->next;
  780.     }
  781.   fwrite ("n", 1, 1, conffile);
  782.   write_comment (conffile, _(exthdr));
  783.   templist = registered_exts;
  784.   while (templist != NULL)
  785.     {
  786.       tempext = templist->data;
  787.       fprintf (conffile, "ext=%s:%s:%c:%sn", tempext->ext, tempext->filename,
  788.        *tempext->ascii_binary == '' ? ' ' : *tempext->ascii_binary,
  789.        tempext->view_program);
  790.       templist = templist->next;
  791.     }
  792.   fwrite ("n", 1, 1, conffile);
  793.   write_comment (conffile, _(histhdr));
  794.   for (templist = localhistory; templist != NULL; templist = templist->next)
  795.     fprintf (conffile, "localhistory=%sn", (char *) templist->data);
  796.   for (templist = remotehistory; templist != NULL; templist = templist->next)
  797.     fprintf (conffile, "remotehistory=%sn", (char *) templist->data);
  798.   for (templist = host_history; templist != NULL; templist = templist->next)
  799.     fprintf (conffile, "hosthistory=%sn", (char *) templist->data);
  800.   for (templist = port_history; templist != NULL; templist = templist->next)
  801.     fprintf (conffile, "porthistory=%sn", (char *) templist->data);
  802.   for (templist = user_history; templist != NULL; templist = templist->next)
  803.     fprintf (conffile, "userhistory=%sn", (char *) templist->data);
  804.   fclose (conffile);
  805. }
  806. void
  807. gftp_write_bookmarks_file (void)
  808. {
  809.   gftp_bookmarks *tempentry;
  810.   char *bmhdr, *tempstr;
  811.   FILE * bmfile;
  812.   bmhdr = N_("Bookmarks file for gFTP. Copyright (C) 1998-2002 Brian Masney <masneyb@gftp.org>. Warning: Any comments that you add to this file WILL be overwritten");
  813.   if ((tempstr = expand_path (BOOKMARKS_FILE)) == NULL)
  814.     {
  815.       printf (_("gFTP Error: Bad bookmarks file name %sn"), CONFIG_FILE);
  816.       exit (0);
  817.     }
  818.   if ((bmfile = fopen (tempstr, "w+")) == NULL)
  819.     {
  820.       printf (_("gFTP Error: Cannot open bookmarks file %s: %sn"),
  821.       CONFIG_FILE, g_strerror (errno));
  822.       exit (0);
  823.     }
  824.   g_free (tempstr);
  825.   write_comment (bmfile, _(bmhdr));
  826.   fwrite ("n", 1, 1, bmfile);
  827.   tempentry = bookmarks->children;
  828.   while (tempentry != NULL)
  829.     {
  830.       if (tempentry->children != NULL)
  831. {
  832.   tempentry = tempentry->children;
  833.   continue;
  834. }
  835.       tempstr = tempentry->path;
  836.       while (*tempstr == '/')
  837. tempstr++;
  838.       fprintf (bmfile,
  839.        "[%s]nhostname=%snport=%dnprotocol=%snremote directory=%snlocal directory=%snusername=%snpassword=%snaccount=%sn",
  840.        tempstr, tempentry->hostname == NULL ? "" : tempentry->hostname,
  841.        tempentry->port, tempentry->protocol == NULL
  842.        || *tempentry->protocol ==
  843.        '' ? gftp_protocols[0].name : tempentry->protocol,
  844.        tempentry->remote_dir == NULL ? "" : tempentry->remote_dir,
  845.        tempentry->local_dir == NULL ? "" : tempentry->local_dir,
  846.        tempentry->user == NULL ? "" : tempentry->user,
  847.        !tempentry->save_password
  848.        || tempentry->pass == NULL ? "" : tempentry->pass,
  849.        tempentry->acct == NULL ? "" : tempentry->acct);
  850.       if (tempentry->sftpserv_path)
  851.         fprintf (bmfile, "sftpserv_path=%sn", tempentry->sftpserv_path);
  852.       fprintf (bmfile, "n");
  853.  
  854.       if (tempentry->next == NULL)
  855. {
  856.   tempentry = tempentry->prev;
  857.   while (tempentry->next == NULL && tempentry->prev != NULL)
  858.     tempentry = tempentry->prev;
  859.   tempentry = tempentry->next;
  860. }
  861.       else
  862. tempentry = tempentry->next;
  863.     }
  864.   fclose (bmfile);
  865. }
  866. static void
  867. write_comment (FILE * fd, const char *comment)
  868. {
  869.   const char *pos, *endpos;
  870.   fwrite ("# ", 1, 2, fd);
  871.   pos = comment;
  872.   while (strlen (pos) > 76)
  873.     {
  874.       for (endpos = pos + 76; *endpos != ' ' && endpos > pos; endpos--);
  875.       if (endpos == pos)
  876. {
  877.   for (endpos = pos + 76; *endpos != ' ' && *endpos != '';
  878.        endpos++);
  879. }
  880.       fwrite (pos, 1, endpos - pos, fd);
  881.       fwrite ("n# ", 1, 3, fd);
  882.       if (*endpos == '')
  883. {
  884.   pos = endpos;
  885.   break;
  886. }
  887.       else
  888. pos = endpos + 1;
  889.     }
  890.   if (strlen (pos) > 1)
  891.     {
  892.       fwrite (pos, 1, strlen (pos), fd);
  893.       fwrite ("n", 1, 1, fd);
  894.     }
  895. }
  896. static int
  897. parse_args (char *str, int numargs, int lineno, char **first, ...)
  898. {
  899.   char *curpos, *endpos, *pos, **dest, tempchar;
  900.   int ret, has_colon;
  901.   va_list argp;
  902.   ret = 1;
  903.   va_start (argp, first);
  904.   curpos = str;
  905.   dest = first;
  906.   *dest = NULL;
  907.   while (numargs > 0)
  908.     {
  909.       has_colon = 0;
  910.       if (numargs > 1)
  911. {
  912.   if ((endpos = strchr (curpos, ':')) == NULL)
  913.     {
  914.       printf (_("gFTP Warning: Line %d doesn't have enough argumentsn"), 
  915.                       lineno);
  916.       ret = 0;
  917.       endpos = curpos + strlen (curpos);
  918.     }
  919.   else
  920.     {
  921.       /* Allow colons inside the fields. If you want a colon inside a 
  922.                  field, just put 2 colons in there */
  923.       while (endpos != NULL && *(endpos - 1) == '\')
  924. {
  925.   endpos = strchr (endpos + 1, ':');
  926.   has_colon = 1;
  927. }
  928.     }
  929. }
  930.       else
  931. endpos = curpos + strlen (curpos);
  932.       *dest = g_malloc (endpos - curpos + 1);
  933.       tempchar = *endpos;
  934.       *endpos = '';
  935.       strcpy (*dest, curpos);
  936.       *endpos = tempchar;
  937.       if (has_colon)
  938. {
  939.   pos = *dest;
  940.   curpos = *dest;
  941.   while (*pos != '')
  942.     {
  943.       if (*pos != '\' && *(pos + 1) != ':')
  944. *curpos++ = *pos++;
  945.       else
  946. pos++;
  947.     }
  948.   *curpos = '';
  949. }
  950.       if (*endpos == '')
  951. break;
  952.       curpos = endpos + 1;
  953.       if (numargs > 1)
  954. {
  955.   dest = va_arg (argp, char **);
  956.   *dest = NULL;
  957. }
  958.       numargs--;
  959.     }
  960.   while (numargs > 1)
  961.     {
  962.       dest = va_arg (argp, char **);
  963.       *dest = g_malloc (1);
  964.       **dest = '';
  965.       numargs--;
  966.     }
  967.   va_end (argp);
  968.   return (1);
  969. }
  970. GHashTable *
  971. build_bookmarks_hash_table (gftp_bookmarks * entry)
  972. {
  973.   gftp_bookmarks * tempentry;
  974.   GHashTable * htable;
  975.   htable = g_hash_table_new (string_hash_function, string_hash_compare);
  976.   tempentry = entry;
  977.   while (tempentry != NULL)
  978.     {
  979.       g_hash_table_insert (htable, tempentry->path, tempentry);
  980.       if (tempentry->children != NULL)
  981. {
  982.   tempentry = tempentry->children;
  983.   continue;
  984. }
  985.       while (tempentry->next == NULL && tempentry->prev != NULL)
  986. tempentry = tempentry->prev;
  987.       tempentry = tempentry->next;
  988.     }
  989.   return (htable);
  990. }
  991. void
  992. print_bookmarks (gftp_bookmarks * bookmarks)
  993. {
  994.   gftp_bookmarks * tempentry;
  995.   tempentry = bookmarks->children;
  996.   while (tempentry != NULL)
  997.     {
  998.       printf ("Path: %s (%d)n", tempentry->path, tempentry->children != NULL);
  999.       if (tempentry->children != NULL)
  1000.         {
  1001.           tempentry = tempentry->children;
  1002.           continue;
  1003.         }
  1004.       if (tempentry->next == NULL)
  1005.         {
  1006.   while (tempentry->next == NULL && tempentry->prev != NULL)
  1007.             tempentry = tempentry->prev;
  1008.           tempentry = tempentry->next;
  1009.         }
  1010.       else
  1011. tempentry = tempentry->next;
  1012.     }
  1013. }