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

Ftp客户端

开发平台:

Visual C++

  1. /*****************************************************************************/
  2. /*  misc.c - general purpose 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. #include "options.h"
  21. static const char cvsid[] = "$Id: misc.c,v 1.16 2002/12/06 02:28:19 masneyb Exp $";
  22. char *
  23. insert_commas (off_t number, char *dest_str, size_t dest_len)
  24. {
  25.   char *frompos, *topos, src[50], *dest;
  26.   int len, num, rem, i;
  27.   if (dest_str != NULL)
  28.     *dest_str = '';
  29.   len = (number > 0 ? log10 (number) : 0) + 2;
  30.   if (len <= 0) 
  31.     {
  32.       if (dest_str != NULL)
  33.         strncpy (dest_str, "0", dest_len);
  34.       else
  35.         dest_str = g_strdup ("0");
  36.       return (dest_str);
  37.     }
  38.   len += len / 3;
  39.   if (dest_str != NULL && len > dest_len)
  40.     {
  41.       
  42.       for (i=0; i<dest_len - 1; i++)
  43.         dest_str[i] = 'X';
  44.       dest_str[dest_len - 1] = '';
  45.       return (dest_str);
  46.     }
  47.   if (dest_str == NULL)
  48.     dest = g_malloc0 (len);
  49.   else
  50.     dest = dest_str;
  51. #if defined (_LARGEFILE_SOURCE)
  52.   g_snprintf (src, sizeof (src), "%lld", number);
  53. #else
  54.   g_snprintf (src, sizeof (src), "%ld", number);
  55. #endif
  56.   num = strlen (src) / 3 - 1;
  57.   rem = strlen (src) % 3;
  58.   frompos = src;
  59.   topos = dest;
  60.   for (i = 0; i < rem; i++)
  61.     *topos++ = *frompos++;
  62.   if (*frompos != '')
  63.     {
  64.       if (rem != 0)
  65. *topos++ = ',';
  66.       while (num > 0)
  67. {
  68.   for (i = 0; i < 3; i++)
  69.     *topos++ = *frompos++;
  70.   *topos++ = ',';
  71.   num--;
  72. }
  73.       for (i = 0; i < 3; i++)
  74. *topos++ = *frompos++;
  75.     }
  76.   *topos = '';
  77.   return (dest);
  78. }
  79. long
  80. file_countlf (int filefd, long endpos)
  81. {
  82.   char tempstr[255];
  83.   long num, mypos;
  84.   ssize_t n;
  85.   int i;
  86.   mypos = num = 0;
  87.   lseek (filefd, 0, SEEK_SET);
  88.   while ((n = read (filefd, tempstr, sizeof (tempstr))) > 0)
  89.     {
  90.       for (i = 0; i < n; i++)
  91. {
  92.   if ((tempstr[i] == 'n') && (i > 0) && (tempstr[i - 1] != 'r')
  93.       && (endpos == 0 || mypos + i <= endpos))
  94.     ++num;
  95. }
  96.       mypos += n;
  97.     }
  98.   lseek (filefd, 0, SEEK_SET);
  99.   return (num);
  100. }
  101. char *
  102. alltrim (char *str)
  103. {
  104.   char *pos, *newpos;
  105.   int diff;
  106.   pos = str + strlen (str) - 1;
  107.   while (pos >= str && *pos == ' ')
  108.     *pos-- = '';
  109.   pos = str;
  110.   diff = 0;
  111.   while (*pos++ == ' ')
  112.     diff++;
  113.   if (diff == 0)
  114.     return (str);
  115.   pos = str + diff;
  116.   newpos = str;
  117.   while (*pos != '')
  118.     *newpos++ = *pos++;
  119.   *newpos = '';
  120.   return (str);
  121. }
  122. char *
  123. expand_path (const char *src)
  124. {
  125.   char *str, *pos, *endpos, *prevpos, *newstr, *tempstr, tempchar;
  126.   struct passwd *pw;
  127.   pw = NULL;
  128.   str = g_malloc (strlen (src) + 1);
  129.   strcpy (str, src);
  130.   if (*str == '~')
  131.     {
  132.       if (*(str + 1) == '/' || *(str + 1) == '')
  133. pw = getpwuid (geteuid ());
  134.       else
  135. {
  136.           if ((pos = strchr (str, '/')) != NULL)
  137.     *pos = '';
  138.   pw = getpwnam (str + 1);
  139.           if (pos != NULL)
  140.             *pos = '/';
  141. }
  142.     }
  143.   endpos = str;
  144.   newstr = NULL;
  145.   while ((pos = strchr (endpos, '/')) != NULL)
  146.     {
  147.       pos++;
  148.       while (*pos == '/')
  149.         pos++;
  150.       if ((endpos = strchr (pos, '/')) == NULL)
  151. endpos = pos + strlen (pos);
  152.       tempchar = *endpos;
  153.       *endpos = '';
  154.       if (strcmp (pos, "..") == 0)
  155. {
  156.   *(pos - 1) = '';
  157.   if (newstr != NULL && (prevpos = strrchr (newstr, '/')) != NULL)
  158.     *prevpos = '';
  159. }
  160.       else if (strcmp (pos, ".") != 0)
  161. {
  162.   if (newstr == NULL)
  163.     newstr = g_strdup (pos - 1);
  164.   else
  165.     {
  166.       tempstr = g_strconcat (newstr, pos - 1, NULL);
  167.       g_free (newstr);
  168.       newstr = tempstr;
  169.     }
  170. }
  171.       *endpos = tempchar;
  172.       if (*endpos == '')
  173. break;
  174.       endpos = pos + 1;
  175.     }
  176.   if (newstr == NULL || *newstr == '')
  177.     {
  178.       if (newstr != NULL)
  179. g_free (newstr);
  180.       newstr = g_malloc0 (2);
  181.       *newstr = '/';
  182.     }
  183.   g_free (str);
  184.   if (pw != NULL)
  185.     {
  186.       if ((pos = strchr (newstr, '/')) == NULL)
  187. {
  188.   str = g_malloc (strlen (pw->pw_dir) + 1);
  189.   strcpy (str, pw->pw_dir);
  190. }
  191.       else
  192. str = g_strconcat (pw->pw_dir, pos, NULL);
  193.       g_free (newstr);
  194.       newstr = str;
  195.     }
  196.   return (newstr);
  197. }
  198. void
  199. remove_double_slashes (char *string)
  200. {
  201.   char *newpos, *oldpos;
  202.   oldpos = newpos = string;
  203.   while (*oldpos != '')
  204.     {
  205.       *newpos++ = *oldpos++;
  206.       if (*oldpos == '')
  207. break;
  208.       while (*(newpos - 1) == '/' && *(oldpos) == '/')
  209. oldpos++;
  210.     }
  211.   *newpos = '';
  212.   if (string[strlen (string) - 1] == '/')
  213.     string[strlen (string) - 1] = '';
  214. }
  215. void
  216. make_nonnull (char **str)
  217. {
  218.   if (*str == NULL)
  219.     *str = g_malloc0 (1);
  220. }
  221. int
  222. copyfile (char *source, char *dest)
  223. {
  224.   int srcfd, destfd;
  225.   char buf[8192];
  226.   ssize_t n;
  227.   if ((srcfd = open (source, O_RDONLY)) == -1)
  228.     {
  229.       printf (_("Error: Cannot open local file %s: %sn"),
  230.               source, g_strerror (errno));
  231.       exit (1);
  232.     }
  233.   if ((destfd = open (dest, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1)
  234.     {
  235.       printf (_("Error: Cannot open local file %s: %sn"),
  236.               dest, g_strerror (errno));
  237.       close (srcfd);
  238.       exit (1);
  239.     }
  240.   while ((n = read (srcfd, buf, sizeof (buf))) > 0)
  241.     {
  242.       if (write (destfd, buf, n) == -1)
  243.         {
  244.           printf (_("Error: Could not write to socket: %sn"), 
  245.                   g_strerror (errno));
  246.           exit (1);
  247.         }
  248.     }
  249.   if (n == -1)
  250.     {
  251.       printf (_("Error: Could not read from socket: %sn"), g_strerror (errno));
  252.       exit (1);
  253.     }
  254.   close (srcfd);
  255.   close (destfd);
  256.   return (1);
  257. }
  258. int
  259. gftp_match_filespec (char *filename, char *filespec)
  260. {
  261.   char *filepos, *wcpos, *pos, *newpos, search_str[20];
  262.   size_t len, curlen;
  263.   
  264.   if (filename == NULL || *filename == '' || 
  265.       filespec == NULL || *filespec == '') 
  266.     return(1);
  267.   filepos = filename;
  268.   wcpos = filespec;
  269.   while(1) 
  270.     {
  271.       if (*wcpos == '') 
  272.         return (1);
  273.       else if (*filepos == '') 
  274.         return(0);
  275.       else if(*wcpos == '?') 
  276.         {
  277.           wcpos++;
  278.           filepos++;
  279.         }
  280.       else if(*wcpos == '*' && *(wcpos+1) == '') 
  281.         return(1);
  282.       else if(*wcpos == '*') 
  283.         {
  284.           len = sizeof (search_str);
  285.           for (pos = wcpos + 1, newpos = search_str, curlen = 0;
  286.                *pos != '*' && *pos != '?' && *pos != '' && curlen < len;
  287.                curlen++, *newpos++ = *pos++);
  288.           *newpos = '';
  289.           if ((filepos = strstr (filepos, search_str)) == NULL)
  290.             return(0);
  291.           wcpos += curlen + 1;
  292.           filepos += curlen;
  293.         }
  294.       else if(*wcpos++ != *filepos++) 
  295.         return(0);
  296.     }
  297.   return (1);
  298. }
  299. int
  300. gftp_parse_command_line (int *argc, char ***argv)
  301. {
  302.   if (*argc > 1)
  303.     {
  304.       if (strcmp (argv[0][1], "--help") == 0 || strcmp (argv[0][1], "-h") == 0)
  305. gftp_usage ();
  306.       else if (strcmp (argv[0][1], "--version") == 0 || strcmp (argv[0][1], "-v") == 0)
  307. {
  308.   printf ("%sn", version);
  309.   exit (0);
  310. }
  311.     }
  312.   return (0);
  313. }
  314. void
  315. gftp_usage (void)
  316. {
  317.   printf (_("usage: gftp [[ftp://][user:[pass]@]ftp-site[:port][/directory]]n"));
  318.   exit (0);
  319. }
  320. char *
  321. get_xpm_path (char *filename, int quit_on_err)
  322. {
  323.   char *tempstr, *exfile;
  324.   tempstr = g_strconcat (BASE_CONF_DIR, "/", filename, NULL);
  325.   exfile = expand_path (tempstr);
  326.   g_free (tempstr);
  327.   if (access (exfile, F_OK) != 0)
  328.     {
  329.       g_free (exfile);
  330.       tempstr = g_strconcat (SHARE_DIR, "/", filename, NULL);
  331.       exfile = expand_path (tempstr);
  332.       g_free (tempstr);
  333.       if (access (exfile, F_OK) != 0)
  334. {
  335.   g_free (exfile);
  336.   exfile = g_strconcat ("/usr/share/icons/", filename, NULL);
  337.   if (access (exfile, F_OK) != 0)
  338.     {
  339.       g_free (exfile);
  340.       if (!quit_on_err)
  341. return (NULL);
  342.       printf (_("gFTP Error: Cannot find file %s in %s or %sn"),
  343.       filename, SHARE_DIR, BASE_CONF_DIR);
  344.       exit (-1);
  345.     }
  346. }
  347.     }
  348.   return (exfile);
  349. }
  350. gint
  351. string_hash_compare (gconstpointer path1, gconstpointer path2)
  352. {
  353.   return (strcmp ((char *) path1, (char *) path2) == 0);
  354. }
  355. guint
  356. string_hash_function (gconstpointer key)
  357. {
  358.   guint ret;
  359.   int i;
  360.   ret = 0;
  361.   for (i=0; ((char *) key)[0] != '' && i < 3; i++)
  362.     ret += ((char *) key)[i];
  363.   return (ret);
  364. }
  365. void
  366. free_file_list (GList * filelist)
  367. {
  368.   gftp_file * tempfle;
  369.   GList * templist;
  370.   templist = filelist;
  371.   while (templist != NULL)
  372.     {
  373.       tempfle = templist->data;
  374.       free_fdata (tempfle);
  375.       templist = templist->next;
  376.     }
  377.   g_list_free (filelist);
  378. }
  379. void
  380. free_fdata (gftp_file * fle)
  381. {
  382.   if (fle->file)
  383.     g_free (fle->file);
  384.   if (fle->user)
  385.     g_free (fle->user);
  386.   if (fle->group)
  387.     g_free (fle->group);
  388.   if (fle->attribs)
  389.     g_free (fle->attribs);
  390.   if (fle->destfile)
  391.     g_free (fle->destfile);
  392.   if (fle->fd > 0)
  393.     close (fle->fd);
  394.   g_free (fle);
  395. }
  396. gftp_file *
  397. copy_fdata (gftp_file * fle)
  398. {
  399.   gftp_file * newfle;
  400.   newfle = g_malloc0 (sizeof (*newfle));
  401.   memcpy (newfle, fle, sizeof (*newfle));
  402.   if (fle->file)
  403.     {
  404.       newfle->file = g_malloc (strlen (fle->file) + 1);
  405.       strcpy (newfle->file, fle->file);
  406.     }
  407.   if (fle->user)
  408.     {
  409.       newfle->user = g_malloc (strlen (fle->user) + 1);
  410.       strcpy (newfle->user, fle->user);
  411.     }
  412.   if (fle->group)
  413.     {
  414.       newfle->group = g_malloc (strlen (fle->group) + 1);
  415.       strcpy (newfle->group, fle->group);
  416.     }
  417.   if (fle->attribs)
  418.     {
  419.       newfle->attribs = g_malloc (strlen (fle->attribs) + 1);
  420.       strcpy (newfle->attribs, fle->attribs);
  421.     }
  422.   if (fle->destfile)
  423.     {
  424.       newfle->destfile = g_malloc (strlen (fle->destfile) + 1);
  425.       strcpy (newfle->destfile, fle->destfile);
  426.     }
  427.   return (newfle);
  428. }
  429. int
  430. compare_request (gftp_request * request1, gftp_request * request2,
  431.                  int compare_dirs)
  432. {
  433.   char *strarr[3][2];
  434.   int i, ret;
  435.   ret = 1;
  436.   if (strcmp (request1->protocol_name, request2->protocol_name) == 0 &&
  437.       request1->port == request2->port)
  438.     {
  439.       strarr[0][0] = request1->hostname;
  440.       strarr[0][1] = request2->hostname;
  441.       strarr[1][0] = request1->username;
  442.       strarr[1][1] = request2->username;
  443.       if (compare_dirs)
  444.         {
  445.           strarr[2][0] = request1->directory;
  446.           strarr[2][1] = request2->directory;
  447.         }
  448.       else
  449.         strarr[2][0] = strarr[2][1] = "";
  450.       for (i = 0; i < 3; i++)
  451.         {
  452.           if ((strarr[i][0] && !strarr[i][1]) ||
  453.               (!strarr[i][0] && strarr[i][1]))
  454.             {
  455.               ret = 0;
  456.               break;
  457.             }
  458.           if (strarr[i][0] && strarr[i][1] &&
  459.               strcmp (strarr[i][0], strarr[i][1]) != 0)
  460.             {
  461.               ret = 0;
  462.               break;
  463.             }
  464.         }
  465.     }
  466.   else
  467.     ret = 0;
  468.   return (ret);
  469. }
  470. void
  471. free_tdata (gftp_transfer * tdata)
  472. {
  473.   if (tdata->statmutex)
  474.     g_free (tdata->statmutex);
  475.   if (tdata->structmutex)
  476.     g_free (tdata->structmutex);
  477.   if (tdata->fromreq != NULL)
  478.     gftp_request_destroy (tdata->fromreq, 1);
  479.   if (tdata->toreq != NULL)
  480.     gftp_request_destroy (tdata->toreq, 1);
  481.   free_file_list (tdata->files);
  482.   g_free (tdata);
  483. }
  484. gftp_request * 
  485. copy_request (gftp_request * req)
  486. {
  487.   gftp_request * newreq;
  488.   newreq = gftp_request_new ();
  489.   if (req->hostname)
  490.     newreq->hostname = g_strdup (req->hostname);
  491.   if (req->username)
  492.     newreq->username = g_strdup (req->username);
  493.   if (req->password)
  494.     newreq->password = g_strdup (req->password);
  495.   if (req->account)
  496.     newreq->account = g_strdup (req->account);
  497.   if (req->directory)
  498.     newreq->directory = g_strdup (req->directory);
  499.   newreq->port = req->port;
  500.   newreq->data_type = req->data_type;
  501.   newreq->use_proxy = req->use_proxy;
  502.   gftp_set_proxy_config (newreq, req->proxy_config);
  503.   newreq->transfer_type = req->transfer_type;
  504.   newreq->network_timeout = req->network_timeout;
  505.   newreq->retries = req->retries;
  506.   newreq->sleep_time = req->sleep_time;
  507.   newreq->passive_transfer = req->passive_transfer;
  508.   newreq->maxkbs = req->maxkbs;
  509.   newreq->logging_function = req->logging_function;
  510.   if (req->sftpserv_path != NULL)
  511.     newreq->sftpserv_path = g_strdup (req->sftpserv_path);
  512.   req->init (newreq);
  513.   return (newreq);
  514. }
  515. int
  516. ptym_open (char *pts_name)
  517. {
  518.   int fd;
  519. #ifdef __sgi
  520.   char *tempstr;
  521.   if ((tempstr = _getpty (&fd, O_RDWR, 0600, 0)) == NULL)
  522.     return (-1);
  523.   strcpy (pts_name, tempstr);
  524.   return (fd);
  525. #else /* !__sgi */
  526. #ifdef SYSV
  527.   char *tempstr;
  528.   strcpy (pts_name, "/dev/ptmx");
  529.   if ((fd = open (pts_name, O_RDWR)) < 0)
  530.     return (-1);
  531.   if (grantpt (fd) < 0)
  532.     {
  533.       close (fd);
  534.       return (-1);
  535.     }
  536.   if (unlockpt (fd) < 0)
  537.     {
  538.       close (fd);
  539.       return (-1);
  540.     }
  541.   if ((tempstr = ptsname (fd)) == NULL)
  542.     {
  543.       close (fd);
  544.       return (-1);
  545.     }
  546.   strcpy (pts_name, tempstr);
  547.   return (fd);
  548. #else /* !SYSV */
  549.   char *pos1, *pos2;
  550.   strcpy (pts_name, "/dev/ptyXY");
  551.   for (pos1 = "pqrstuvwxyzPQRST"; *pos1 != ''; pos1++) 
  552.     {
  553.       pts_name[8] = *pos1;
  554.       for (pos2 = "0123456789abcdef"; *pos2 != ''; pos2++)
  555.         {
  556.           pts_name[9] = *pos2;
  557.           if ((fd = open (pts_name, O_RDWR)) < 0)
  558.             continue;
  559.           pts_name[5] = 't';
  560.           return (fd);
  561.         }
  562.     }
  563.   return (-1);
  564. #endif
  565. #endif
  566. }
  567. int
  568. ptys_open (int fdm, char *pts_name)
  569. {
  570.   int fds;
  571. #if !defined (SYSV) && !defined (__sgi)
  572.   chmod (pts_name, S_IRUSR | S_IWUSR);
  573.   chown (pts_name, getuid (), -1);
  574. #endif
  575.   if ((fds = open (pts_name, O_RDWR)) < 0)
  576.     {
  577.       close (fdm);
  578.       return (-1);
  579.     }
  580. #ifdef SYSV
  581.   if (ioctl (fds, I_PUSH, "ptem") < 0)
  582.     {
  583.       close (fdm);
  584.       close (fds);
  585.       return (-1);
  586.     }
  587.   if (ioctl (fds, I_PUSH, "ldterm") < 0)
  588.     {
  589.       close (fdm);
  590.       close (fds);
  591.       return (-1);
  592.     }
  593.   if (ioctl (fds, I_PUSH, "ttcompat") < 0)
  594.     {
  595.       close (fdm);
  596.       close (fds);
  597.       return (-1);
  598.     }
  599. #endif
  600. #if !defined(SYSV) && !defined (__sgi) && defined(TIOCSCTTY) && !defined(CIBAUD)
  601.   if (ioctl (fds, TIOCSCTTY, (char *) 0) < 0)
  602.     {
  603.       close (fdm);
  604.       return (-1);
  605.     }
  606. #endif
  607.   return (fds);
  608. }
  609. int
  610. tty_raw (int fd)
  611. {
  612.   struct termios buf;
  613.   if (tcgetattr (fd, &buf) < 0)
  614.     return (-1);
  615.   buf.c_iflag |= IGNPAR;
  616.   buf.c_iflag &= ~(ICRNL | ISTRIP | IXON | IGNCR | IXANY | IXOFF | INLCR);
  617.   buf.c_lflag &= ~(ECHO | ICANON | ISIG | ECHOE | ECHOK | ECHONL);
  618. #ifdef IEXTEN
  619.   buf.c_lflag &= ~(IEXTEN);
  620. #endif
  621.   buf.c_oflag &= ~(OPOST);
  622.   buf.c_cc[VMIN] = 1;
  623.   buf.c_cc[VTIME] = 0;
  624.   if (tcsetattr (fd, TCSADRAIN, &buf) < 0)
  625.     return (-1);
  626.   return (0);
  627. }
  628. /* We have the caller send us a pointer to a string so we can write the port
  629.    into it. It makes it easier so we don't have to worry about freeing it 
  630.    later on, the caller can just send us an auto variable, The string
  631.    should be at least 6 chars. I know this is messy... */
  632. char **
  633. make_ssh_exec_args (gftp_request * request, char *execname, 
  634.                     int use_sftp_subsys, char *portstring)
  635. {
  636.   char **args, *oldstr, *tempstr;
  637.   struct servent serv_struct;
  638.   int i, j;
  639.   args = g_malloc (sizeof (char *) * (num_ssh_extra_params + 15));
  640.   args[0] = ssh_prog_name != NULL && *ssh_prog_name != '' ? 
  641.             ssh_prog_name : "ssh";
  642.   i = 1;
  643.   tempstr = g_strdup (args[0]);
  644.   if (ssh_extra_params_list != NULL)
  645.     {
  646.       for (j=0; ssh_extra_params_list[j] != NULL; j++)
  647.         {
  648.           oldstr = tempstr;
  649.           args[i++] = ssh_extra_params_list[j];
  650.           tempstr = g_strconcat (oldstr, " ", ssh_extra_params_list[j], NULL);
  651.           g_free (oldstr);
  652.         }
  653.     }
  654.   oldstr = tempstr;
  655.   tempstr = g_strconcat (oldstr, " -e none", NULL);
  656.   g_free (oldstr);
  657.   args[i++] = "-e";
  658.   args[i++] = "none";
  659.   if (request->username && *request->username != '')
  660.     {
  661.       oldstr = tempstr;
  662.       tempstr = g_strconcat (oldstr, " -l ", request->username, NULL);
  663.       g_free (oldstr);
  664.       args[i++] = "-l";
  665.       args[i++] = request->username;
  666.     }
  667.   if (request->port != 0)
  668.     {
  669.       g_snprintf (portstring, 6, "%d", request->port);
  670.       oldstr = tempstr;
  671.       tempstr = g_strconcat (oldstr, " -p ", portstring, NULL);
  672.       g_free (oldstr);
  673.       args[i++] = "-p";
  674.       args[i++] = portstring;
  675.     }
  676.   else
  677.     {
  678.       if (!r_getservbyname ("ssh", "tcp", &serv_struct, NULL))
  679.         request->port = 22;
  680.       else
  681.         request->port = ntohs (serv_struct.s_port);
  682.     }
  683.   if (use_sftp_subsys)
  684.     {
  685.       oldstr = tempstr;
  686.       tempstr = g_strconcat (oldstr, " ", request->hostname, " -s sftp", NULL);
  687.       g_free (oldstr);
  688.       args[i++] = request->hostname;
  689.       args[i++] = "-s";
  690.       args[i++] = "sftp";
  691.       args[i] = NULL;
  692.     }
  693.   else
  694.     {
  695.       oldstr = tempstr;
  696.       tempstr = g_strconcat (oldstr, " ", request->hostname, " "", execname, 
  697.                              """, NULL);
  698.       g_free (oldstr);
  699.       args[i++] = request->hostname;
  700.       args[i++] = execname;
  701.       args[i] = NULL;
  702.     }
  703.   request->logging_function (gftp_logging_misc, request->user_data, 
  704.                              _("Running program %sn"), tempstr);
  705.   g_free (tempstr);
  706.   return (args);
  707. }
  708. #define SSH_LOGIN_BUFSIZE 200
  709. #define SSH_ERROR_BADPASS -1
  710. #define SSH_ERROR_QUESTION -2
  711. #define SSH_WARNING  -3
  712. char *
  713. ssh_start_login_sequence (gftp_request * request, int fd)
  714. {
  715.   char *tempstr, *pwstr, *tmppos;
  716.   size_t rem, len, diff, lastdiff, key_pos;
  717.   int wrotepw, ok;
  718.   ssize_t rd;
  719.   rem = len = SSH_LOGIN_BUFSIZE;
  720.   tempstr = g_malloc0 (len + 1);
  721.   key_pos = diff = lastdiff = 0;
  722.   wrotepw = 0;
  723.   ok = 1;
  724.   if (gftp_set_sockblocking (request, fd, 1) == -1)
  725.     return (NULL);
  726.   pwstr = g_strconcat (request->password, "n", NULL);
  727.   errno = 0;
  728.   while (1)
  729.     {
  730.       if ((rd = gftp_read (request, tempstr + diff, rem - 1, fd)) <= 0)
  731.         {
  732.           ok = 0;
  733.           break;
  734.         }
  735.       rem -= rd;
  736.       diff += rd;
  737.       tempstr[diff] = ''; 
  738.       if (diff > 11 && strcmp (tempstr + diff - 10, "password: ") == 0)
  739.         {
  740.           if (wrotepw)
  741.             {
  742.               ok = SSH_ERROR_BADPASS;
  743.               break;
  744.             }
  745.           if (strstr (tempstr, "WARNING") != NULL ||
  746.               strstr (tempstr, _("WARNING")) != NULL)
  747.             {
  748.               ok = SSH_WARNING;
  749.               break;
  750.             }
  751.               
  752.           wrotepw = 1;
  753.           if (gftp_write (request, pwstr, strlen (pwstr), fd) < 0)
  754.             {
  755.               ok = 0;
  756.               break;
  757.             }
  758.         }
  759.       else if (diff > 2 && strcmp (tempstr + diff - 2, ": ") == 0 &&
  760.                ((tmppos = strstr (tempstr + key_pos, "Enter passphrase for RSA key")) != NULL ||
  761.                 ((tmppos = strstr (tempstr + key_pos, "Enter passphrase for key '")) != NULL)))
  762.         {
  763.           key_pos = diff;
  764.           if (wrotepw)
  765.             {
  766.               ok = SSH_ERROR_BADPASS;
  767.               break;
  768.             }
  769.           if (strstr (tempstr, "WARNING") != NULL ||
  770.               strstr (tempstr, _("WARNING")) != NULL)
  771.             {
  772.               ok = SSH_WARNING;
  773.               break;
  774.             }
  775.           wrotepw = 1;
  776.           if (gftp_write (request, pwstr, strlen (pwstr), fd) < 0)
  777.             {
  778.               ok = 0;
  779.               break;
  780.             }
  781.         }
  782.       else if (diff > 10 && strcmp (tempstr + diff - 10, "(yes/no)? ") == 0)
  783.         {
  784.           ok = SSH_ERROR_QUESTION;
  785.           break;
  786.         }
  787.       else if (diff >= 5 && strcmp (tempstr + diff - 5, "xsftp") == 0)
  788.         break;
  789.       else if (rem <= 1)
  790.         {
  791.           request->logging_function (gftp_logging_recv, request->user_data,
  792.                                      "%s", tempstr + lastdiff);
  793.           len += SSH_LOGIN_BUFSIZE;
  794.           rem += SSH_LOGIN_BUFSIZE;
  795.           lastdiff = diff;
  796.           tempstr = g_realloc (tempstr, len);
  797.           continue;
  798.         }
  799.     }
  800.   g_free (pwstr);
  801.   if (*(tempstr + lastdiff) != '')
  802.     request->logging_function (gftp_logging_recv, request->user_data,
  803.                                "%sn", tempstr + lastdiff);
  804.   if (ok <= 0)
  805.     {
  806.       if (ok == SSH_ERROR_BADPASS)
  807.         request->logging_function (gftp_logging_error, request->user_data,
  808.                                _("Error: An incorrect password was enteredn"));
  809.       else if (ok == SSH_ERROR_QUESTION)
  810.         request->logging_function (gftp_logging_error, request->user_data,
  811.                                _("Please connect to this host with the command line SSH utility and answer this question appropriately.n"));
  812.       else if (ok == SSH_WARNING)
  813.         request->logging_function (gftp_logging_error, request->user_data,
  814.                                    _("Please correct the above warning to connect to this host.n"));
  815.       g_free (tempstr);
  816.       return (NULL);
  817.     }
  818.  
  819.   return (tempstr);
  820. }
  821. #ifdef G_HAVE_GINT64
  822. gint64
  823. hton64 (gint64 val)
  824. {
  825.   gint64 num;
  826.   char *pos;
  827.   num = 0;
  828.   pos = (char *) &num;
  829.   pos[0] = (val >> 56) & 0xff;
  830.   pos[1] = (val >> 48) & 0xff;
  831.   pos[2] = (val >> 40) & 0xff;
  832.   pos[3] = (val >> 32) & 0xff;
  833.   pos[4] = (val >> 24) & 0xff;
  834.   pos[5] = (val >> 16) & 0xff;
  835.   pos[6] = (val >> 8) & 0xff;
  836.   pos[7] = val & 0xff;
  837.   return (num);
  838. }
  839. #endif
  840. static gint
  841. gftp_file_sort_function_as (gconstpointer a, gconstpointer b)
  842. {
  843.   const gftp_file * f1, * f2;
  844.   f1 = a;
  845.   f2 = b;
  846.   return (strcmp (f1->file, f2->file));
  847. }
  848. static gint
  849. gftp_file_sort_function_ds (gconstpointer a, gconstpointer b)
  850. {
  851.   const gftp_file * f1, * f2;
  852.   gint ret;
  853.   f1 = a;
  854.   f2 = b;
  855.   ret = strcmp (f1->file, f2->file);
  856.   if (ret < 0)
  857.     ret = 1;
  858.   else if (ret > 0)
  859.     ret = -1;
  860.   return (ret);
  861. }
  862. static gint
  863. gftp_user_sort_function_as (gconstpointer a, gconstpointer b)
  864. {
  865.   const gftp_file * f1, * f2;
  866.   f1 = a;
  867.   f2 = b;
  868.   return (strcmp (f1->user, f2->user));
  869. }
  870. static gint
  871. gftp_user_sort_function_ds (gconstpointer a, gconstpointer b)
  872. {
  873.   const gftp_file * f1, * f2;
  874.   gint ret;
  875.   f1 = a;
  876.   f2 = b;
  877.   ret = strcmp (f1->user, f2->user);
  878.   if (ret < 0)
  879.     ret = 1;
  880.   else if (ret > 0)
  881.     ret = -1;
  882.   return (ret);
  883. }
  884. static gint
  885. gftp_group_sort_function_as (gconstpointer a, gconstpointer b)
  886. {
  887.   const gftp_file * f1, * f2;
  888.   f1 = a;
  889.   f2 = b;
  890.   return (strcmp (f1->group, f2->group));
  891. }
  892. static gint
  893. gftp_group_sort_function_ds (gconstpointer a, gconstpointer b)
  894. {
  895.   const gftp_file * f1, * f2;
  896.   gint ret;
  897.   f1 = a;
  898.   f2 = b;
  899.   ret = strcmp (f1->group, f2->group);
  900.   if (ret < 0)
  901.     ret = 1;
  902.   else if (ret > 0)
  903.     ret = -1;
  904.   return (ret);
  905. }
  906. static gint
  907. gftp_attribs_sort_function_as (gconstpointer a, gconstpointer b)
  908. {
  909.   const gftp_file * f1, * f2;
  910.   f1 = a;
  911.   f2 = b;
  912.   return (strcmp (f1->attribs, f2->attribs));
  913. }
  914. static gint
  915. gftp_attribs_sort_function_ds (gconstpointer a, gconstpointer b)
  916. {
  917.   const gftp_file * f1, * f2;
  918.   gint ret;
  919.   f1 = a;
  920.   f2 = b;
  921.   ret = strcmp (f1->attribs, f2->attribs);
  922.   if (ret < 0)
  923.     ret = 1;
  924.   else if (ret > 0)
  925.     ret = -1;
  926.   return (ret);
  927. }
  928. static gint
  929. gftp_size_sort_function_as (gconstpointer a, gconstpointer b)
  930. {
  931.   const gftp_file * f1, * f2;
  932.   f1 = a;
  933.   f2 = b;
  934.   if (f1->size < f2->size)
  935.     return (-1);
  936.   else if (f1->size == f2->size)
  937.     return (0);
  938.   else
  939.     return (1);
  940. }
  941. static gint
  942. gftp_size_sort_function_ds (gconstpointer a, gconstpointer b)
  943. {
  944.   const gftp_file * f1, * f2;
  945.   f1 = a;
  946.   f2 = b;
  947.   if (f1->size < f2->size)
  948.     return (1);
  949.   else if (f1->size == f2->size)
  950.     return (0);
  951.   else
  952.     return (-1);
  953. }
  954. static gint
  955. gftp_datetime_sort_function_as (gconstpointer a, gconstpointer b)
  956. {
  957.   const gftp_file * f1, * f2;
  958.   f1 = a;
  959.   f2 = b;
  960.   if (f1->datetime < f2->datetime)
  961.     return (-1);
  962.   else if (f1->datetime == f2->datetime)
  963.     return (0);
  964.   else
  965.     return (1);
  966. }
  967. static gint
  968. gftp_datetime_sort_function_ds (gconstpointer a, gconstpointer b)
  969. {
  970.   const gftp_file * f1, * f2;
  971.   f1 = a;
  972.   f2 = b;
  973.   if (f1->datetime < f2->datetime)
  974.     return (1);
  975.   else if (f1->datetime == f2->datetime)
  976.     return (0);
  977.   else
  978.     return (-1);
  979. }
  980. GList *
  981. gftp_sort_filelist (GList * filelist, int column, int asds)
  982. {
  983.   GList * files, * dirs, * dotdot, * tempitem, * insitem;
  984.   GCompareFunc sortfunc;
  985.   gftp_file * tempfle;
  986.   files = dirs = dotdot = NULL;
  987.   if (column == GFTP_SORT_COL_FILE)
  988.     sortfunc = asds ?  gftp_file_sort_function_as : gftp_file_sort_function_ds;
  989.   else if (column == GFTP_SORT_COL_SIZE)
  990.     sortfunc = asds ?  gftp_size_sort_function_as : gftp_size_sort_function_ds;
  991.   else if (column == GFTP_SORT_COL_USER)
  992.     sortfunc = asds ?  gftp_user_sort_function_as : gftp_user_sort_function_ds;
  993.   else if (column == GFTP_SORT_COL_GROUP)
  994.     sortfunc = asds ?
  995.                 gftp_group_sort_function_as : gftp_group_sort_function_ds;
  996.   else if (column == GFTP_SORT_COL_DATETIME)
  997.     sortfunc = asds ?
  998.                 gftp_datetime_sort_function_as : gftp_datetime_sort_function_ds;  else /* GFTP_SORT_COL_ATTRIBS */
  999.     sortfunc = asds ? 
  1000.                 gftp_attribs_sort_function_as : gftp_attribs_sort_function_ds;
  1001.   for (tempitem = filelist; tempitem != NULL; )
  1002.     {
  1003.       tempfle = tempitem->data;
  1004.       insitem = tempitem;
  1005.       tempitem = tempitem->next;
  1006.       insitem->next = NULL;
  1007.       if (dotdot == NULL && strcmp (tempfle->file, "..") == 0)
  1008.         dotdot = insitem;
  1009.       else if (sort_dirs_first && tempfle->isdir)
  1010.         {
  1011.           insitem->next = dirs;
  1012.           dirs = insitem;
  1013.         }
  1014.       else
  1015.         {
  1016.           insitem->next = files;
  1017.           files = insitem;
  1018.         }
  1019.     }
  1020.   if (dirs != NULL)
  1021.     dirs = g_list_sort (dirs, sortfunc);
  1022.   if (files != NULL)
  1023.     files = g_list_sort (files, sortfunc);
  1024.   filelist = dotdot;
  1025.   if (filelist == NULL)
  1026.     filelist = dirs;
  1027.   else
  1028.     filelist = g_list_concat (filelist, dirs);
  1029.   if (filelist == NULL)
  1030.     filelist = files;
  1031.   else
  1032.     filelist = g_list_concat (filelist, files);
  1033.   /* I haven't check this, but I'm pretty sure some older versions of glib
  1034.      had a bug that the prev pointer wasn't being sent to NULL */
  1035.   filelist->prev = NULL;
  1036.   return (filelist);
  1037. }