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

Ftp客户端

开发平台:

Visual C++

  1. /*****************************************************************************/
  2. /*  misc-gtk.c - misc stuff for the gtk+ 1.2 port of gftp                    */
  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., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  18. /*****************************************************************************/
  19. #include <gftp-gtk.h>
  20. static const char cvsid[] = "$Id: misc-gtk.c,v 1.19 2002/12/03 02:22:32 masneyb Exp $";
  21. static pthread_mutex_t netfunclock = PTHREAD_MUTEX_INITIALIZER;
  22. static GtkWidget * statuswid;
  23. void
  24. remove_files_window (gftp_window_data * wdata)
  25. {
  26.   wdata->show_selected = 0;
  27.   gtk_clist_freeze (GTK_CLIST (wdata->listbox));
  28.   gtk_clist_clear (GTK_CLIST (wdata->listbox));
  29.   free_file_list (wdata->files);
  30.   wdata->files = NULL;
  31.   gtk_clist_thaw (GTK_CLIST (wdata->listbox));
  32. }
  33. void
  34. ftp_log (gftp_logging_level level, void *ptr, const char *string, ...)
  35. {
  36.   int upd, free_logstr;
  37.   gftp_log * newlog;
  38.   char *logstr;
  39.   gint delsize;
  40.   va_list argp;
  41.   guint len;
  42. #if GTK_MAJOR_VERSION == 1
  43.   gftp_color * color;
  44.   GdkColor fore;
  45. #else
  46.   GtkTextBuffer * textbuf;
  47.   GtkTextIter iter, iter2;
  48.   gsize bread, bwrite;
  49.   const char *descr;
  50.   char *tempstr;
  51. #endif
  52.   if (pthread_self () != main_thread_id)
  53.     {
  54.       newlog = g_malloc0 (sizeof (*newlog));
  55.       newlog->type = level;
  56.       va_start (argp, string);
  57.       newlog->msg = g_strdup_vprintf (string, argp);
  58.       va_end (argp);
  59.       pthread_mutex_lock (&log_mutex);
  60.       file_transfer_logs = g_list_append (file_transfer_logs, newlog);
  61.       pthread_mutex_unlock (&log_mutex);
  62.       return;
  63.     }
  64.   va_start (argp, string);
  65.   if (strcmp (string, "%s") == 0)
  66.     {
  67.       logstr = va_arg (argp, char *);
  68.       free_logstr = 0;
  69.     }
  70.   else
  71.     {
  72.       logstr = g_strdup_vprintf (string, argp);
  73.       free_logstr = 1;
  74.     }
  75.   va_end (argp);
  76.   if (logfd != NULL)
  77.     {
  78.       if (fwrite (logstr, strlen (logstr), 1, logfd) != 1)
  79.         {
  80.           fclose (logfd);
  81.           logfd = NULL;
  82.         }
  83.       else
  84.         {
  85.           fflush (logfd);
  86.           if (ferror (logfd))
  87.             {
  88.               fclose (logfd);
  89.               logfd = NULL;
  90.             }
  91.         }
  92.     }
  93.   upd = logwdw_vadj->upper - logwdw_vadj->page_size == logwdw_vadj->value;
  94. #if GTK_MAJOR_VERSION == 1
  95.   switch (level)
  96.     {
  97.       case gftp_logging_send:
  98.         color = &send_color;
  99.         break;
  100.       case gftp_logging_recv:
  101.         color = &recv_color;
  102.         break;
  103.       case gftp_logging_error:
  104.         color = &error_color;
  105.         break;
  106.       default:
  107.         color = &misc_color;
  108.         break;
  109.     }
  110.   memset (&fore, 0, sizeof (fore));
  111.   fore.red = color->red;
  112.   fore.green = color->green;
  113.   fore.blue = color->blue;
  114.   gtk_text_freeze (GTK_TEXT (logwdw));
  115.   gtk_text_insert (GTK_TEXT (logwdw), NULL, &fore, NULL, logstr, -1);
  116.   len = gtk_text_get_length (GTK_TEXT (logwdw));
  117.   if (max_log_window_size > 0 && len > max_log_window_size)
  118.     {
  119.       delsize = len - max_log_window_size;
  120.       gtk_text_set_point (GTK_TEXT (logwdw), delsize);
  121.       gtk_text_backward_delete (GTK_TEXT (logwdw), delsize);
  122.       len = max_log_window_size;
  123.     }
  124.   gtk_text_set_point (GTK_TEXT (logwdw), len);
  125.   gtk_text_thaw (GTK_TEXT (logwdw));
  126.   if (upd)
  127.     gtk_adjustment_set_value (logwdw_vadj, logwdw_vadj->upper);
  128. #else
  129.   switch (level)
  130.     {
  131.       case gftp_logging_send:
  132.         descr = "send";
  133.         break;
  134.       case gftp_logging_recv:
  135.         descr = "recv";
  136.         break;
  137.       case gftp_logging_error:
  138.         descr = "error";
  139.         break;
  140.       default:
  141.         descr = "misc";
  142.         break;
  143.     }
  144.   /* If the current log message is not in UTF8 format, convert it to UTF8 
  145.      format based on the current locale */
  146.   if (!g_utf8_validate (logstr, -1, NULL))
  147.     {
  148.       tempstr = g_locale_to_utf8 (logstr, -1, &bread, &bwrite, NULL);
  149.       if (tempstr != NULL)
  150.         {
  151.           if (free_logstr)
  152.             g_free (logstr);
  153.           logstr = tempstr;
  154.           free_logstr = 1;
  155.         }
  156.     }
  157.   textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (logwdw));
  158.   len = gtk_text_buffer_get_char_count (textbuf);
  159.   gtk_text_buffer_get_iter_at_offset (textbuf, &iter, len);
  160.   gtk_text_buffer_insert_with_tags_by_name (textbuf, &iter, logstr, -1, 
  161.                                             descr, NULL);
  162.   if (upd)
  163.     {
  164.       gtk_text_buffer_move_mark (textbuf, logwdw_textmark, &iter);
  165.       gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (logwdw), logwdw_textmark,
  166.                                      0, 1, 1, 1);
  167.     }
  168.   if (max_log_window_size > 0)
  169.     {
  170.       delsize = len + g_utf8_strlen (logstr, -1) - max_log_window_size;
  171.       if (delsize > 0)
  172.         {
  173.           gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0);
  174.           gtk_text_buffer_get_iter_at_offset (textbuf, &iter2, delsize);
  175.           gtk_text_buffer_delete (textbuf, &iter, &iter2);
  176.         }
  177.     }
  178. #endif
  179.   if (free_logstr)
  180.     g_free (logstr);
  181. }
  182. void
  183. refresh (gftp_window_data * wdata)
  184. {
  185.   if (!check_status (_("Refresh"), wdata, 0, 0, 0, 1))
  186.     return;
  187.   gtk_clist_freeze (GTK_CLIST (wdata->listbox));
  188.   remove_files_window (wdata);
  189.   gftp_delete_cache_entry (wdata->request, 0);
  190.   ftp_list_files (wdata, 0);
  191.   gtk_clist_thaw (GTK_CLIST (wdata->listbox));
  192. }
  193. void
  194. update_window_info (void)
  195. {
  196.   char *tempstr, empty[] = "";
  197.   GtkWidget * tempwid;
  198.   int i;
  199.   if (current_wdata->request != NULL)
  200.     {
  201.       if ((tempstr = GFTP_GET_HOSTNAME (current_wdata->request)) == NULL)
  202.         tempstr = empty;
  203.       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (hostedit)->entry), tempstr);
  204.       if ((tempstr = GFTP_GET_USERNAME (current_wdata->request)) == NULL)
  205.         tempstr = empty;
  206.       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (useredit)->entry), tempstr);
  207.       if ((tempstr = GFTP_GET_PASSWORD (current_wdata->request)) == NULL)
  208.         tempstr = empty;
  209.       gtk_entry_set_text (GTK_ENTRY (passedit), tempstr);
  210.       if (GFTP_GET_PORT (current_wdata->request) != 0)
  211.         {
  212.           tempstr = g_strdup_printf ("%d", GFTP_GET_PORT (current_wdata->request));
  213.           gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (portedit)->entry), tempstr);
  214.           g_free (tempstr);
  215.         }
  216.      for (i=0; gftp_protocols[i].init != NULL; i++)
  217.        {
  218.          if (current_wdata->request->init == gftp_protocols[i].init)
  219.            {
  220.              gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), i);
  221.              break;
  222.            }
  223.        }
  224.     }
  225.   update_window (&window1);
  226.   update_window (&window2);
  227.   tempwid = gtk_item_factory_get_widget (factory, menus[tools_start+2].path);
  228.   gtk_widget_set_sensitive (tempwid, GFTP_IS_CONNECTED (window1.request) 
  229.     && GFTP_IS_CONNECTED (window2.request));
  230. }
  231. static void
  232. set_menu_sensitive (gftp_window_data * wdata, char *path, int sensitive)
  233. {
  234.   GtkWidget * tempwid;
  235.   char * pos;
  236.   tempwid = NULL;
  237.   if (factory != NULL)
  238.     tempwid = gtk_item_factory_get_widget (factory, path);
  239.   if (tempwid)
  240.     gtk_widget_set_sensitive (tempwid, sensitive);
  241.   if ((pos = strchr (path + 1, '/')) == NULL)
  242.     pos = path;
  243.   if (wdata->ifactory)
  244.     tempwid = gtk_item_factory_get_widget (wdata->ifactory, pos);
  245.   if (tempwid)
  246.     gtk_widget_set_sensitive (tempwid, sensitive);
  247. }
  248. void
  249. update_window (gftp_window_data * wdata)
  250. {
  251.   char *dir, *tempstr, *temp1str, *fspec;
  252.   int connected, start;
  253.   connected = GFTP_IS_CONNECTED (wdata->request);
  254.   if (connected)
  255.     {
  256.       fspec = wdata->show_selected ? "Selected" : strcmp (wdata->filespec, "*") == 0 ?  _("All Files") : wdata->filespec;
  257.       if ((temp1str = GFTP_GET_HOSTNAME (wdata->request)) == NULL ||
  258.           wdata->request->protonum == GFTP_LOCAL_NUM)
  259. temp1str = "";
  260.       tempstr = g_strconcat (temp1str, *temp1str == '' ? "[" : " [",
  261.      GFTP_GET_PROTOCOL_NAME (wdata->request),
  262.      wdata->request->cached ? _("] (Cached) [") : "] [",
  263.                      fspec, "]", current_wdata == wdata ? "*" : "", NULL);
  264.       gtk_label_set (GTK_LABEL (wdata->hoststxt), tempstr);
  265.       g_free (tempstr);
  266.       if ((dir = GFTP_GET_DIRECTORY (wdata->request)) == NULL)
  267.         temp1str = "";
  268.       else
  269.         temp1str = dir;
  270.       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (wdata->combo)->entry),temp1str);
  271.     }
  272.   else if (wdata->hoststxt != NULL)
  273.     {
  274.       tempstr = g_strconcat (_("Not connected"), 
  275.                              current_wdata == wdata ? "*" : "", NULL);
  276.       gtk_label_set (GTK_LABEL (wdata->hoststxt), tempstr);
  277.       g_free (tempstr);
  278.       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (wdata->combo)->entry), "");
  279.     }
  280.   if (wdata == &window1)
  281.     start = local_start;
  282.   else
  283.     start = remote_start;
  284.   set_menu_sensitive (wdata, menus[start + 3].path, connected && 
  285.                       strcmp (wdata->request->url_prefix, "file") != 0);
  286.   set_menu_sensitive (wdata, menus[start + 5].path, connected);
  287.   set_menu_sensitive (wdata, menus[start + 6].path, connected);
  288.   set_menu_sensitive (wdata, menus[start + 7].path, connected);
  289.   set_menu_sensitive (wdata, menus[start + 8].path, connected);
  290.   set_menu_sensitive (wdata, menus[start + 9].path, connected);
  291.   set_menu_sensitive (wdata, menus[start + 11].path, connected);
  292.   set_menu_sensitive (wdata, menus[start + 12].path, connected &&
  293.                       wdata->request->site != NULL);
  294.   set_menu_sensitive (wdata, menus[start + 13].path, connected &&
  295.                       wdata->request->chdir!= NULL);
  296.   set_menu_sensitive (wdata, menus[start + 14].path, connected &&
  297.                       wdata->request->chmod != NULL);
  298.   set_menu_sensitive (wdata, menus[start + 15].path, connected &&
  299.                       wdata->request->mkdir != NULL);
  300.   set_menu_sensitive (wdata, menus[start + 16].path, connected &&
  301.                       wdata->request->rename != NULL);
  302.   set_menu_sensitive (wdata, menus[start + 17].path, connected &&
  303.                       wdata->request->rmdir != NULL &&
  304.                       wdata->request->rmfile != NULL);
  305.   set_menu_sensitive (wdata, menus[start + 18].path, connected &&
  306.                       wdata->request->get_file != NULL);
  307.   set_menu_sensitive (wdata, menus[start + 19].path, connected &&
  308.                       wdata->request->get_file != NULL);
  309.   set_menu_sensitive (wdata, menus[start + 20].path, connected);
  310. }  
  311. GtkWidget *
  312. toolbar_pixmap (GtkWidget * widget, char *filename)
  313. {
  314.   gftp_graphic * graphic;
  315.   GtkWidget *pix;
  316.   if (filename == NULL || *filename == '')
  317.     return (NULL);
  318.   graphic = open_xpm (widget, filename);
  319.   if (graphic == NULL)
  320.     return (NULL);
  321.     
  322.   if ((pix = gtk_pixmap_new (graphic->pixmap, graphic->bitmap)) == NULL)
  323.     return (NULL);
  324.   gtk_widget_show (pix);
  325.   return (pix);
  326. }
  327. gftp_graphic *
  328. open_xpm (GtkWidget * widget, char *filename)
  329. {
  330.   gftp_graphic * graphic;
  331.   GtkStyle *style;
  332.   char *exfile;
  333.   if ((graphic = g_hash_table_lookup (graphic_hash_table, filename)) != NULL)
  334.     return (graphic);
  335.   style = gtk_widget_get_style (widget);
  336.   if ((exfile = get_xpm_path (filename, 0)) == NULL)
  337.     return (NULL);
  338.   graphic = g_malloc0 (sizeof (*graphic));
  339.   graphic->pixmap = gdk_pixmap_create_from_xpm (widget->window, 
  340.                         &graphic->bitmap, &style->bg[GTK_STATE_NORMAL], exfile);
  341.   g_free (exfile);
  342.   if (graphic->pixmap == NULL)
  343.     {
  344.       g_free (graphic);
  345.       ftp_log (gftp_logging_error, NULL, _("Error opening file %s: %sn"), 
  346.                exfile, g_strerror (errno));
  347.       return (NULL);
  348.     }
  349.   graphic->filename = g_malloc (strlen (filename) + 1);
  350.   strcpy (graphic->filename, filename);
  351.   g_hash_table_insert (graphic_hash_table, graphic->filename, graphic);
  352.   return (graphic);
  353. }
  354. void
  355. gftp_free_pixmap (char *filename)
  356. {
  357.   gftp_graphic * graphic;
  358.   if ((graphic = g_hash_table_lookup (graphic_hash_table, filename)) == NULL)
  359.     return;
  360. #if GTK_MAJOR_VERSION == 1
  361.   gdk_pixmap_unref (graphic->pixmap);
  362.   gdk_bitmap_unref (graphic->bitmap);
  363. #else
  364.   g_object_unref (graphic->pixmap);
  365.   g_object_unref (graphic->bitmap);
  366. #endif
  367.   g_hash_table_remove (graphic_hash_table, filename);
  368.   g_free (graphic->filename);
  369.   g_free (graphic);
  370. }
  371. void
  372. gftp_get_pixmap (GtkWidget * widget, char *filename, GdkPixmap ** pix,
  373.                  GdkBitmap ** bitmap)
  374. {
  375.   gftp_graphic * graphic;
  376.   if (filename == NULL || *filename == '')
  377.     {
  378.       *pix = NULL;
  379.       *bitmap = NULL;
  380.       return;
  381.     }
  382.   if ((graphic = g_hash_table_lookup (graphic_hash_table, filename)) == NULL)
  383.     graphic = open_xpm (widget, filename);
  384.   if (graphic == NULL)
  385.     {
  386.       *pix = NULL;
  387.       *bitmap = NULL;
  388.       return;
  389.     }
  390.   *pix = graphic->pixmap;
  391.   *bitmap = graphic->bitmap;
  392. }
  393. int
  394. check_status (char *name, gftp_window_data *wdata, int check_other_stop,
  395.               int only_one, int at_least_one, int func)
  396. {
  397.   gftp_window_data * owdata;
  398.   owdata = wdata == &window1 ? &window2 : &window1;
  399.   if (wdata->request->stopable)
  400.     {
  401.       ftp_log (gftp_logging_misc, NULL,
  402.        _("%s: Please hit the stop button first to do anything elsen"),
  403.        name);
  404.       return (0);
  405.     }
  406.   if (check_other_stop && owdata->request->stopable)
  407.     {
  408.       ftp_log (gftp_logging_misc, NULL,
  409.        _("%s: Please hit the stop button first to do anything elsen"),
  410.        name);
  411.       return (0);
  412.     }
  413.   if (!GFTP_IS_CONNECTED (wdata->request))
  414.     {
  415.       ftp_log (gftp_logging_misc, NULL,
  416.        _("%s: Not connected to a remote siten"), name);
  417.       return (0);
  418.     }
  419.   if (!func)
  420.     {
  421.       ftp_log (gftp_logging_misc, NULL,
  422.        _("%s: This feature is not available using this protocoln"),
  423.        name);
  424.       return (0);
  425.     }
  426.   if (only_one && !IS_ONE_SELECTED (wdata))
  427.     {
  428.       ftp_log (gftp_logging_misc, NULL,
  429.        _("%s: You must only have one item selectedn"), name);
  430.       return (0);
  431.     }
  432.   if (at_least_one && !only_one && IS_NONE_SELECTED (wdata))
  433.     {
  434.       ftp_log (gftp_logging_misc, NULL,
  435.        _("%s: You must have at least one item selectedn"), name);
  436.       return (0);
  437.     }
  438.   return (1);
  439. }
  440. static gchar *
  441. gftp_item_factory_translate (const char *path,
  442.      gpointer    func_data)
  443. {
  444.   const gchar *strip_prefix = func_data;
  445.   const char *result;
  446.   
  447.   if (strip_prefix)
  448.     {
  449.       char *tmp_path = g_strconcat (strip_prefix, path, NULL);
  450.       result = gettext (tmp_path);
  451.       if (result == tmp_path)
  452. result = path;
  453.       g_free (tmp_path);
  454.     }
  455.   else
  456.     result = gettext (path);
  457.   return (char *)result;
  458. }
  459. GtkItemFactory *
  460. item_factory_new (GtkType container_type, const char *path,
  461.   GtkAccelGroup *accel_group, const char *strip_prefix)
  462. {
  463.   GtkItemFactory *result = gtk_item_factory_new (container_type, path, accel_group);
  464.   gchar *strip_prefix_dup = g_strdup (g_strdup (strip_prefix));
  465.   
  466.   gtk_item_factory_set_translate_func (result, gftp_item_factory_translate,
  467.        strip_prefix_dup, NULL);
  468.   if (strip_prefix_dup)
  469.     gtk_object_set_data_full (GTK_OBJECT (result), "gftp-strip-prefix",
  470.       strip_prefix_dup, (GDestroyNotify)g_free);
  471.   return result;
  472. }
  473. void
  474. create_item_factory (GtkItemFactory * ifactory, guint n_entries,
  475.      GtkItemFactoryEntry * entries, gpointer callback_data)
  476. {
  477.   int i;
  478.   const char *strip_prefix = gtk_object_get_data (GTK_OBJECT (ifactory), "gftp-strip-prefix");
  479.   int strip_prefix_len = 0;
  480.   if (strip_prefix)
  481.     strip_prefix_len = strlen (strip_prefix);
  482.   for (i = 0; i < n_entries; i++)
  483.     {
  484.       GtkItemFactoryEntry dummy_item = entries[i];
  485.       if (strip_prefix && strncmp (entries[i].path, strip_prefix, strip_prefix_len) == 0)
  486. dummy_item.path += strip_prefix_len;
  487.       
  488.       gtk_item_factory_create_item (ifactory, &dummy_item, callback_data, 1);
  489.     }
  490. }
  491. GList *
  492. get_next_selection (GList * selection, GList ** list, int *curnum)
  493. {
  494.   gftp_file * tempfle;
  495.   int i, newpos;
  496.   newpos = (int) selection->data;
  497.   i = *curnum - newpos;
  498.   if (i < 0)
  499.     {
  500.       while (i != 0)
  501.         {
  502.           tempfle = (*list)->data;
  503.           if (tempfle->shown)
  504.             {
  505.       ++*curnum;
  506.       i++;
  507.             }
  508.   *list = (*list)->next;
  509.         }     
  510.     }
  511.   else if (i > 0)
  512.     {
  513.       while (i != 0)
  514.         {
  515.           tempfle = (*list)->data;
  516.           if (tempfle->shown)
  517.             {
  518.       --*curnum;
  519.       i--;
  520.             }
  521.   *list = (*list)->prev;
  522.         }
  523.     }
  524.   tempfle = (*list)->data;
  525.   while ((*list)->next && !tempfle->shown)
  526.     {
  527.       *list = (*list)->next;
  528.       tempfle = (*list)->data;
  529.     }
  530.   return (selection->next);
  531. }
  532. void
  533. add_history (GtkWidget * widget, GList ** history, unsigned int *histlen, 
  534.              const char *str)
  535. {
  536.   GList *node, *delnode;
  537.   char *tempstr;
  538.   int i;
  539.   if (str == NULL || *str == '')
  540.     return;
  541.   for (node = *history; node != NULL; node = node->next)
  542.     {
  543.       if (strcmp ((char *) node->data, str) == 0)
  544. break;
  545.     }
  546.   if (node == NULL)
  547.     {
  548.       if (*histlen >= MAX_HIST_LEN)
  549. {
  550.   node = *history;
  551.   for (i = 1; i < MAX_HIST_LEN; i++)
  552.     node = node->next;
  553.   node->prev->next = NULL;
  554.   node->prev = NULL;
  555.   delnode = node;
  556.   while (delnode != NULL)
  557.     {
  558.       if (delnode->data)
  559. g_free (delnode->data);
  560.       delnode = delnode->next;
  561.     }
  562.   g_list_free (node);
  563. }
  564.       tempstr = g_malloc (strlen (str) + 1);
  565.       strcpy (tempstr, str);
  566.       *history = g_list_prepend (*history, tempstr);
  567.       ++*histlen;
  568.     }
  569.   else if (node->prev != NULL)
  570.     {
  571.       node->prev->next = node->next;
  572.       if (node->next != NULL)
  573. node->next->prev = node->prev;
  574.       node->prev = NULL;
  575.       node->next = *history;
  576.       if (node->next != NULL)
  577. node->next->prev = node;
  578.       *history = node;
  579.     }
  580.   gtk_combo_set_popdown_strings (GTK_COMBO (widget), *history);
  581. }
  582. int
  583. check_reconnect (gftp_window_data *wdata)
  584. {
  585.   return (wdata->request->cached && wdata->request->sockfd < 0 && 
  586.           !wdata->request->always_connected &&
  587.   !ftp_connect (wdata, wdata->request, 0) ? -1 : 0);
  588. }
  589. void
  590. add_file_listbox (gftp_window_data * wdata, gftp_file * fle)
  591. {
  592.   char *add_data[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }, *pos;
  593.   gftp_file_extensions * tempext;
  594.   char *tempstr, *str;
  595.   GdkBitmap * bitmap;
  596.   GList * templist;
  597.   GdkPixmap * pix;
  598.   int clist_num;
  599.   size_t stlen;
  600.   if (wdata->show_selected)
  601.     {
  602.       fle->shown = fle->was_sel;
  603.       if (!fle->shown)
  604.         return;
  605.     }
  606.   else if ((!show_hidden_files && *fle->file == '.' && 
  607.             strcmp (fle->file, "..") != 0) ||
  608.            !gftp_match_filespec (fle->file, wdata->filespec))
  609.     {
  610.       fle->shown = 0;
  611.       fle->was_sel = 0;
  612.       return;
  613.     }
  614.   else
  615.     fle->shown = 1;
  616.   clist_num = gtk_clist_append (GTK_CLIST (wdata->listbox), add_data);
  617.   if (fle->was_sel)
  618.     {
  619.       fle->was_sel = 0;
  620.       gtk_clist_select_row (GTK_CLIST (wdata->listbox), clist_num, 0);
  621.     }
  622.   pix = NULL;
  623.   bitmap = NULL;
  624.   if (strcmp (fle->file, "..") == 0)
  625.     gftp_get_pixmap (wdata->listbox, "dotdot.xpm", &pix, &bitmap);
  626.   else if (fle->islink && fle->isdir)
  627.     gftp_get_pixmap (wdata->listbox, "linkdir.xpm", &pix, &bitmap);
  628.   else if (fle->islink)
  629.     gftp_get_pixmap (wdata->listbox, "linkfile.xpm", &pix, &bitmap);
  630.   else if (fle->isdir)
  631.     gftp_get_pixmap (wdata->listbox, "dir.xpm", &pix, &bitmap);
  632.   else if (fle->isexe)
  633.     gftp_get_pixmap (wdata->listbox, "exe.xpm", &pix, &bitmap); 
  634.   else
  635.     {
  636.       stlen = strlen (fle->file);
  637.       templist = registered_exts;
  638.       while (templist != NULL)
  639.         {
  640.           tempext = templist->data;
  641.           if (stlen >= tempext->stlen &&
  642.               strcmp (&fle->file[stlen - tempext->stlen], tempext->ext) == 0)
  643.             {
  644.               if (toupper (*tempext->ascii_binary) == 'A')
  645.                 fle->ascii = 1;
  646.               gftp_get_pixmap (wdata->listbox, tempext->filename, &pix, 
  647.                                &bitmap);
  648.               break;
  649.             }
  650.           templist = templist->next;
  651.         }
  652.     }
  653.   if (pix == NULL && bitmap == NULL)
  654.     gftp_get_pixmap (wdata->listbox, "doc.xpm", &pix, &bitmap);
  655.    
  656.   gtk_clist_set_pixmap (GTK_CLIST (wdata->listbox), clist_num, 0, pix, bitmap);
  657.   if (fle->file)
  658.     gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 1, fle->file);
  659.   if (fle->attribs && (*fle->attribs == 'b' || *fle->attribs == 'c'))
  660.     tempstr = g_strdup_printf ("%d, %d", major (fle->size),
  661.                                minor (fle->size));
  662.   else
  663.     tempstr = insert_commas (fle->size, NULL, 0);
  664.   gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 2, tempstr);
  665.   g_free (tempstr);
  666.   if (fle->user)
  667.     gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 3, fle->user);
  668.   if (fle->group)
  669.     gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 4, fle->group);
  670.   if ((str = ctime (&fle->datetime)))
  671.     {
  672.       if ((pos = strchr (str, 'n')) != NULL)
  673.         *pos = '';
  674.       gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 5, str);
  675.     }
  676.   if (fle->attribs)
  677.     gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 6, fle->attribs);
  678. }
  679. #if GTK_MAJOR_VERSION == 1
  680. static void
  681. ok_dialog_response (GtkWidget * widget, gftp_dialog_data * ddata)
  682. {
  683.   if (ddata->edit == NULL)
  684.     gtk_widget_destroy (ddata->dialog);
  685.  
  686.   if (ddata->yesfunc != NULL)
  687.     ddata->yesfunc (ddata->yespointer, ddata);
  688.   if (ddata->edit != NULL)
  689.     gtk_widget_destroy (ddata->dialog);
  690.   g_free (ddata);
  691. }
  692. static void
  693. cancel_dialog_response (GtkWidget * widget, gftp_dialog_data * ddata)
  694. {
  695.   if (ddata->edit == NULL)
  696.     gtk_widget_destroy (ddata->dialog);
  697.  
  698.   if (ddata->nofunc != NULL)
  699.     ddata->nofunc (ddata->nopointer, ddata);
  700.   if (ddata->edit != NULL)
  701.     gtk_widget_destroy (ddata->dialog);
  702.   g_free (ddata);
  703. }
  704. #else
  705. static void
  706. dialog_response (GtkWidget * widget, gint response, gftp_dialog_data * ddata)
  707. {
  708.   if (ddata->edit == NULL)
  709.     gtk_widget_destroy (ddata->dialog);
  710.   switch (response)
  711.     {
  712.       case GTK_RESPONSE_YES:
  713.         if (ddata->yesfunc != NULL)
  714.           ddata->yesfunc (ddata->yespointer, ddata);
  715.         break;
  716.       default:
  717.         if (ddata->nofunc != NULL)
  718.           ddata->nofunc (ddata->nopointer, ddata);
  719.         break;
  720.     }
  721.   if (ddata->edit != NULL)
  722.     gtk_widget_destroy (ddata->dialog);
  723.   g_free (ddata);
  724. }
  725. #endif
  726. static gint
  727. dialog_keypress (GtkWidget * widget, GdkEventKey * event, gpointer data)
  728. {
  729.   if (event->type != GDK_KEY_PRESS)
  730.     return (FALSE);
  731.   if (event->keyval == GDK_KP_Enter || event->keyval == GDK_Return)
  732.     {
  733. #if GTK_MAJOR_VERSION == 1
  734.       ok_dialog_response (widget, data);
  735. #else
  736.       dialog_response (widget, GTK_RESPONSE_YES, data);
  737. #endif
  738.       return (TRUE);
  739.     }
  740.   else if (event->keyval == GDK_Escape)
  741.     {
  742. #if GTK_MAJOR_VERSION == 1
  743.       cancel_dialog_response (widget, data);
  744. #else
  745.       dialog_response (widget, GTK_RESPONSE_NO, data);
  746. #endif
  747.       return (TRUE);
  748.     }
  749.   return (FALSE);
  750. }
  751. void
  752. MakeEditDialog (char *diagtxt, char *infotxt, char *deftext, int passwd_item,
  753. char *checktext, 
  754.                 gftp_dialog_button okbutton, void (*okfunc) (), void *okptr,
  755. void (*cancelfunc) (), void *cancelptr)
  756. {
  757.   GtkWidget * tempwid, * dialog;
  758.   gftp_dialog_data * ddata;
  759.   const gchar * yes_text;
  760.   ddata = g_malloc (sizeof (*ddata));
  761.   ddata->yesfunc = okfunc;
  762.   ddata->yespointer = okptr;
  763.   ddata->nofunc = cancelfunc;
  764.   ddata->nopointer = cancelptr;
  765. #if GTK_MAJOR_VERSION == 1
  766.   dialog = gtk_dialog_new ();
  767.   gtk_window_set_title (GTK_WINDOW (dialog), diagtxt);
  768.   gtk_grab_add (dialog);
  769.   gtk_container_border_width (GTK_CONTAINER
  770.       (GTK_DIALOG (dialog)->action_area), 5);
  771.   gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 15);
  772.   gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dialog)->action_area), TRUE);
  773. #else
  774.   switch (okbutton)
  775.     {
  776.       case gftp_dialog_button_create:
  777.         yes_text = GTK_STOCK_ADD;
  778.         break;
  779.       case gftp_dialog_button_change:
  780.         yes_text = _("Change");
  781.         break;
  782.       case gftp_dialog_button_connect:
  783.         yes_text = _("Connect");
  784.         break;
  785.       case gftp_dialog_button_rename:
  786.         yes_text = _("Rename");
  787.         break;
  788.       default:
  789.         yes_text = GTK_STOCK_MISSING_IMAGE;
  790.         break;
  791.     }
  792.   dialog = gtk_dialog_new_with_buttons (_(diagtxt), NULL, 0,
  793.                                         yes_text,
  794.                                         GTK_RESPONSE_YES,
  795.                                         GTK_STOCK_CANCEL,
  796.                                         GTK_RESPONSE_NO,
  797.                                         NULL);
  798. #endif
  799.   gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 10);
  800.   gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 5);
  801.   gtk_window_set_wmclass (GTK_WINDOW(dialog), "edit", "gFTP");
  802.   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
  803.   gtk_widget_realize (dialog);
  804.   if (gftp_icon != NULL)
  805.     {
  806.       gdk_window_set_icon (dialog->window, NULL, gftp_icon->pixmap,
  807.                            gftp_icon->bitmap);
  808.       gdk_window_set_icon_name (dialog->window, _("gFTP Icon"));
  809.     }
  810.   ddata->dialog = dialog;
  811.   tempwid = gtk_label_new (infotxt);
  812.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), tempwid, TRUE,
  813.       TRUE, 0);
  814.   gtk_widget_show (tempwid);
  815.   ddata->edit = gtk_entry_new ();
  816.   gtk_signal_connect (GTK_OBJECT (ddata->edit), "key_press_event",
  817.                       GTK_SIGNAL_FUNC (dialog_keypress), (gpointer) ddata);
  818.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), ddata->edit, TRUE,
  819.       TRUE, 0);
  820.   gtk_widget_grab_focus (ddata->edit);
  821.   gtk_entry_set_visibility (GTK_ENTRY (ddata->edit), passwd_item);
  822.   if (deftext != NULL)
  823.     {
  824.       gtk_entry_set_text (GTK_ENTRY (ddata->edit), deftext);
  825.       gtk_entry_select_region (GTK_ENTRY (ddata->edit), 0, strlen (deftext));
  826.     }
  827.   gtk_widget_show (ddata->edit);
  828.   if (checktext != NULL)
  829.     {
  830.       ddata->checkbox = gtk_check_button_new_with_label (checktext);
  831.       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
  832.                           ddata->checkbox, TRUE, TRUE, 0);
  833.       gtk_widget_show (ddata->checkbox);
  834.     }
  835.       
  836. #if GTK_MAJOR_VERSION == 1
  837.   switch (okbutton)
  838.     {
  839.       case gftp_dialog_button_create:
  840.         yes_text = _("Add");
  841.         break;
  842.       case gftp_dialog_button_change:
  843.         yes_text = _("Change");
  844.         break;
  845.       case gftp_dialog_button_connect:
  846.         yes_text = _("Connect");
  847.         break;
  848.       case gftp_dialog_button_rename:
  849.         yes_text = _("Rename");
  850.         break;
  851.       default:
  852.         yes_text = "";
  853.         break;
  854.     }
  855.   tempwid = gtk_button_new_with_label (yes_text);
  856.   GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
  857.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
  858.       TRUE, TRUE, 0);
  859.   gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
  860.                       GTK_SIGNAL_FUNC (ok_dialog_response),
  861.                       ddata);
  862.   gtk_widget_grab_default (tempwid);
  863.   gtk_widget_show (tempwid);
  864.   tempwid = gtk_button_new_with_label (_("Cancel"));
  865.   GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
  866.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
  867.       TRUE, TRUE, 0);
  868.   gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
  869.                       GTK_SIGNAL_FUNC (cancel_dialog_response),
  870.                       ddata);
  871.   gtk_widget_show (tempwid);
  872. #else
  873.   g_signal_connect (GTK_OBJECT (dialog), "response",
  874.                     G_CALLBACK (dialog_response), ddata);
  875. #endif
  876.   gtk_widget_show (dialog);
  877. }
  878. void
  879. MakeYesNoDialog (char *diagtxt, char *infotxt, 
  880.                  void (*yesfunc) (), gpointer yespointer, 
  881.                  void (*nofunc) (), gpointer nopointer)
  882. {
  883.   GtkWidget * text, * dialog;
  884.   gftp_dialog_data * ddata;
  885. #if GTK_MAJOR_VERSION == 1
  886.   GtkWidget * tempwid;
  887. #endif
  888.   ddata = g_malloc (sizeof (*ddata));
  889.   ddata->yesfunc = yesfunc;
  890.   ddata->yespointer = yespointer;
  891.   ddata->nofunc = nofunc;
  892.   ddata->nopointer = nopointer;
  893. #if GTK_MAJOR_VERSION == 1
  894.   dialog = gtk_dialog_new ();
  895.   gtk_grab_add (dialog);
  896.   gtk_window_set_title (GTK_WINDOW (dialog), diagtxt);
  897.   gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 
  898.                               5);
  899.   gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 15);
  900.   gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dialog)->action_area), TRUE);
  901. #else
  902.   dialog = gtk_dialog_new_with_buttons (_(diagtxt), NULL, 0,
  903.                                         GTK_STOCK_YES,
  904.                                         GTK_RESPONSE_YES,
  905.                                         GTK_STOCK_NO,
  906.                                         GTK_RESPONSE_NO,
  907.                                         NULL);
  908. #endif
  909.   gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 10);
  910.   gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 5);
  911.   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
  912.   gtk_window_set_wmclass (GTK_WINDOW(dialog), "yndiag", "gFTP");
  913.   gtk_widget_realize (dialog);
  914.   if (gftp_icon != NULL)
  915.     {
  916.       gdk_window_set_icon (dialog->window, NULL, gftp_icon->pixmap,
  917.                            gftp_icon->bitmap);
  918.       gdk_window_set_icon_name (dialog->window, _("gFTP Icon"));
  919.     }
  920.   ddata->dialog = dialog;
  921.   text = gtk_label_new (infotxt);
  922.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), text, TRUE, TRUE, 0);
  923.   gtk_widget_show (text);
  924. #if GTK_MAJOR_VERSION == 1
  925.   tempwid = gtk_button_new_with_label (_("  Yes  "));
  926.   GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
  927.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
  928.                       FALSE, FALSE, 0);
  929.   gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
  930.                       GTK_SIGNAL_FUNC (ok_dialog_response), ddata);
  931.   gtk_widget_grab_default (tempwid);
  932.   gtk_widget_show (tempwid);
  933.   tempwid = gtk_button_new_with_label (_("  No  "));
  934.   GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT);
  935.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid,
  936.                       FALSE, FALSE, 0);
  937.   gtk_signal_connect (GTK_OBJECT (tempwid), "clicked",
  938.                       GTK_SIGNAL_FUNC (cancel_dialog_response), ddata);
  939.   gtk_widget_show (tempwid);
  940. #else
  941.   g_signal_connect (GTK_OBJECT (dialog), "response",
  942.                     G_CALLBACK (dialog_response), ddata);
  943. #endif
  944.   gtk_widget_show (dialog);
  945. }
  946. static gint
  947. delete_event (GtkWidget * widget, GdkEvent * event, gpointer data)
  948. {
  949.   return (TRUE);
  950. }
  951. static void
  952. trans_stop_button (GtkWidget * widget, gpointer data)
  953. {
  954.   gftp_transfer * transfer;
  955.   transfer = data;
  956.   pthread_kill (((gftp_window_data *) transfer->fromwdata)->tid, SIGINT);
  957. }
  958. void
  959. update_directory_download_progress (gftp_transfer * transfer)
  960. {
  961.   static GtkWidget * dialog = NULL, * textwid, * stopwid;
  962.   char tempstr[255];
  963.   GtkWidget * vbox;
  964.   if (transfer->numfiles < 0 || transfer->numdirs < 0)
  965.     {
  966.       if (dialog != NULL)
  967.         gtk_widget_destroy (dialog);
  968.       dialog = NULL;
  969.       return;
  970.     }
  971.   if (dialog == NULL)
  972.     {
  973.       dialog = gtk_window_new (GTK_WINDOW_POPUP);
  974.       gtk_grab_add (dialog);
  975.       gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
  976.                           GTK_SIGNAL_FUNC (delete_event), NULL);
  977.       gtk_window_set_title (GTK_WINDOW (dialog),
  978.     _("Getting directory listings"));
  979.       gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
  980.       gtk_window_set_wmclass (GTK_WINDOW(dialog), "dirlist", "gFTP");
  981.       vbox = gtk_vbox_new (FALSE, 5);
  982.       gtk_container_border_width (GTK_CONTAINER (vbox), 10);
  983.       gtk_container_add (GTK_CONTAINER (dialog), vbox);
  984.       gtk_widget_show (vbox);
  985.       textwid = gtk_label_new (NULL);
  986.       gtk_box_pack_start (GTK_BOX (vbox), textwid, TRUE, TRUE, 0);
  987.       gtk_widget_show (textwid);
  988.       statuswid = gtk_progress_bar_new ();
  989.       gtk_progress_set_activity_mode (GTK_PROGRESS (statuswid), 1);
  990.       gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (statuswid), 3);
  991.       gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (statuswid), 5);
  992.       gtk_box_pack_start (GTK_BOX (vbox), statuswid, TRUE, TRUE, 0);
  993.       gtk_widget_show (statuswid);
  994.       stopwid = gtk_button_new_with_label (_("  Stop  "));
  995.       gtk_signal_connect (GTK_OBJECT (stopwid), "clicked",
  996.                           GTK_SIGNAL_FUNC (trans_stop_button), transfer);
  997.       gtk_box_pack_start (GTK_BOX (vbox), stopwid, TRUE, TRUE, 0);
  998.       gtk_widget_show (stopwid); 
  999.       gtk_widget_show (dialog);
  1000.     }
  1001.   g_snprintf (tempstr, sizeof (tempstr),
  1002.               _("Received %ld directoriesnand %ld files"), 
  1003.               transfer->numdirs, transfer->numfiles);
  1004.   gtk_label_set_text (GTK_LABEL (textwid), tempstr);
  1005. }
  1006. void *
  1007. generic_thread (void * (*func) (void *), gftp_window_data * wdata)
  1008. {
  1009.   void * ret;
  1010.   if (wdata->request->use_threads)
  1011.     {
  1012.       wdata->request->stopable = 1;
  1013.       gtk_widget_set_sensitive (stop_btn, 1);
  1014.       pthread_create (&wdata->tid, NULL, func, wdata);
  1015.       while (wdata->request->stopable)
  1016.         {
  1017.           GDK_THREADS_LEAVE ();
  1018. #if GTK_MAJOR_VERSION == 1
  1019.           g_main_iteration (TRUE);
  1020. #else
  1021.           g_main_context_iteration (NULL, TRUE);
  1022. #endif
  1023.         }
  1024.       pthread_join (wdata->tid, &ret);
  1025.       gtk_widget_set_sensitive (stop_btn, 0);
  1026.     }
  1027.   else
  1028.     ret = func (wdata);
  1029.   if (!GFTP_IS_CONNECTED (wdata->request))
  1030.     disconnect (wdata);
  1031.   return (ret); 
  1032. }
  1033. int
  1034. progress_timeout (gpointer data)
  1035. {
  1036.   gftp_transfer * tdata;
  1037.   double val;
  1038.   tdata = data;
  1039.   update_directory_download_progress (tdata);
  1040.   val = gtk_progress_get_value (GTK_PROGRESS (statuswid));
  1041.   if (val >= 1.0)
  1042.     val = 0;
  1043.   else
  1044.     val += 0.10;
  1045.   gtk_progress_bar_update (GTK_PROGRESS_BAR (statuswid), val);
  1046.   return (1);
  1047. }
  1048. void
  1049. display_cached_logs (void)
  1050. {
  1051.   gftp_log * templog;
  1052.   GList * templist; 
  1053.   pthread_mutex_lock (&log_mutex);
  1054.   templist = file_transfer_logs;
  1055.   while (templist != NULL)
  1056.     { 
  1057.       templog = (gftp_log *) templist->data;
  1058.       ftp_log (templog->type, (void *) 0x2, "%s", templog->msg);
  1059.       g_free (templog->msg);
  1060.       g_free (templog); 
  1061.       templist->data = NULL;
  1062.       templist = templist->next;
  1063.     }
  1064.   g_list_free (file_transfer_logs);
  1065.   file_transfer_logs = NULL;
  1066.   pthread_mutex_unlock (&log_mutex);
  1067. }
  1068. RETSIGTYPE 
  1069. signal_handler (int signo)
  1070. {
  1071.   signal (signo, signal_handler);
  1072.   if (use_jmp_environment)
  1073.     siglongjmp (jmp_environment, signo == SIGINT ? 1 : 2);
  1074.   else if (signo == SIGINT)
  1075.     exit (1);
  1076. }
  1077. #if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR)
  1078. struct hostent *
  1079. r_gethostbyname (const char *name, struct hostent *result_buf, int *h_errnop)
  1080. {
  1081.   struct hostent *hent;
  1082.   pthread_mutex_lock (&netfunclock);
  1083.   if ((hent = gethostbyname (name)) == NULL)
  1084.     {
  1085.       if (h_errnop)
  1086.         *h_errnop = h_errno;
  1087.     }
  1088.   else
  1089.     {
  1090.       *result_buf = *hent;
  1091.       hent = result_buf;
  1092.     }
  1093.   pthread_mutex_unlock (&netfunclock);
  1094.   return (hent);
  1095. }
  1096. #endif /* !HAVE_GETADDRINFO */
  1097. struct servent *
  1098. r_getservbyname (const char *name, const char *proto,
  1099.                  struct servent *result_buf, int *h_errnop)
  1100. {
  1101.   struct servent *sent;
  1102.   pthread_mutex_lock (&netfunclock);
  1103.   if ((sent = getservbyname (name, proto)) == NULL)
  1104.     {
  1105.       if (h_errnop)
  1106.         *h_errnop = h_errno;
  1107.     }
  1108.   else
  1109.     {
  1110.       *result_buf = *sent;
  1111.       sent = result_buf;
  1112.     }
  1113.   pthread_mutex_unlock (&netfunclock);
  1114.   return (sent);
  1115. }