comparison lib/sshv2.c @ 489:913ea2819842

2004-6-27 Brian Masney <masneyb@gftp.org> * lib/sshv2.c - did more code cleanups
author masneyb
date Sun, 27 Jun 2004 15:32:57 +0000
parents dd22103b9552
children 527d5b926928
comparison
equal deleted inserted replaced
488:73df78f0f204 489:913ea2819842
167 strcpy (buf + 4, str); 167 strcpy (buf + 4, str);
168 } 168 }
169 169
170 170
171 static char * 171 static char *
172 sshv2_initialize_string_with_path (gftp_request * request, const char *path, size_t *len) 172 sshv2_initialize_string_with_path (gftp_request * request, const char *path,
173 size_t *len, char **endpos)
173 { 174 {
174 char *ret, *tempstr; 175 char *ret, *tempstr;
176 size_t pathlen;
175 177
176 if (*path == '/') 178 if (*path == '/')
177 { 179 {
178 *len = strlen (path) + 8 + *len; 180 pathlen = strlen (path);
181 *len = pathlen + 8 + *len;
179 ret = sshv2_initialize_string (request, *len); 182 ret = sshv2_initialize_string (request, *len);
180 sshv2_add_string_to_buf (ret + 4, path); 183 sshv2_add_string_to_buf (ret + 4, path);
181 } 184 }
182 else 185 else
183 { 186 {
184 tempstr = g_strconcat (request->directory, "/", path, NULL); 187 tempstr = gftp_build_path (request->directory, path, NULL);
185 *len = strlen (tempstr) + 8 + *len; 188 pathlen = strlen (tempstr);
189 *len = pathlen + 8 + *len;
186 ret = sshv2_initialize_string (request, *len); 190 ret = sshv2_initialize_string (request, *len);
187 sshv2_add_string_to_buf (ret + 4, tempstr); 191 sshv2_add_string_to_buf (ret + 4, tempstr);
188 g_free (tempstr); 192 g_free (tempstr);
189 } 193 }
194
195 if (endpos != NULL)
196 *endpos = ret + 8 + pathlen;
190 197
191 return (ret); 198 return (ret);
192 } 199 }
193 200
194 201
1006 { 1013 {
1007 request->logging_function (gftp_logging_error, request, 1014 request->logging_function (gftp_logging_error, request,
1008 _("Received wrong response from server, disconnecting\n")); 1015 _("Received wrong response from server, disconnecting\n"));
1009 sshv2_message_free (&message); 1016 sshv2_message_free (&message);
1010 gftp_disconnect (request); 1017 gftp_disconnect (request);
1011
1012 return (GFTP_EFATAL); 1018 return (GFTP_EFATAL);
1013 } 1019 }
1014 1020
1015 sshv2_message_free (&message); 1021 sshv2_message_free (&message);
1016 1022
1372 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); 1378 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL);
1373 1379
1374 if (request->directory != directory) 1380 if (request->directory != directory)
1375 { 1381 {
1376 len = 0; 1382 len = 0;
1377 tempstr = sshv2_initialize_string_with_path (request, directory, &len); 1383 tempstr = sshv2_initialize_string_with_path (request, directory,
1384 &len, NULL);
1378 1385
1379 ret = sshv2_send_command (request, SSH_FXP_REALPATH, tempstr, len); 1386 ret = sshv2_send_command (request, SSH_FXP_REALPATH, tempstr, len);
1380 1387
1381 g_free (tempstr); 1388 g_free (tempstr);
1382 if (ret < 0) 1389 if (ret < 0)
1417 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1424 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1418 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); 1425 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL);
1419 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); 1426 g_return_val_if_fail (directory != NULL, GFTP_EFATAL);
1420 1427
1421 len = 0; 1428 len = 0;
1422 tempstr = sshv2_initialize_string_with_path (request, directory, &len); 1429 tempstr = sshv2_initialize_string_with_path (request, directory, &len, NULL);
1423 1430
1424 ret = sshv2_send_command (request, SSH_FXP_RMDIR, tempstr, len); 1431 ret = sshv2_send_command (request, SSH_FXP_RMDIR, tempstr, len);
1425 1432
1426 g_free (tempstr); 1433 g_free (tempstr);
1427 if (ret < 0) 1434 if (ret < 0)
1452 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1459 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1453 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); 1460 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL);
1454 g_return_val_if_fail (file != NULL, GFTP_EFATAL); 1461 g_return_val_if_fail (file != NULL, GFTP_EFATAL);
1455 1462
1456 len = 0; 1463 len = 0;
1457 tempstr = sshv2_initialize_string_with_path (request, file, &len); 1464 tempstr = sshv2_initialize_string_with_path (request, file, &len, NULL);
1458 1465
1459 ret = sshv2_send_command (request, SSH_FXP_REMOVE, tempstr, len); 1466 ret = sshv2_send_command (request, SSH_FXP_REMOVE, tempstr, len);
1460 1467
1461 g_free (tempstr); 1468 g_free (tempstr);
1462 if (ret < 0) 1469 if (ret < 0)
1477 1484
1478 1485
1479 static int 1486 static int
1480 sshv2_chmod (gftp_request * request, const char *file, int mode) 1487 sshv2_chmod (gftp_request * request, const char *file, int mode)
1481 { 1488 {
1482 char *tempstr, buf[10]; 1489 char *tempstr, *endpos, buf[10];
1483 sshv2_params * params; 1490 sshv2_params * params;
1484 sshv2_message message; 1491 sshv2_message message;
1485 gint32 num; 1492 gint32 num;
1486 size_t len; 1493 size_t len;
1487 int ret; 1494 int ret;
1490 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); 1497 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL);
1491 g_return_val_if_fail (file != NULL, GFTP_EFATAL); 1498 g_return_val_if_fail (file != NULL, GFTP_EFATAL);
1492 1499
1493 params = request->protocol_data; 1500 params = request->protocol_data;
1494 1501
1495 if (*file == '/') 1502 len = 8; /* For attributes */
1496 { 1503 tempstr = sshv2_initialize_string_with_path (request, file, &len, &endpos);
1497 len = strlen (file) + 16;
1498 tempstr = g_malloc (len + 1);
1499 strcpy (tempstr + 8, file);
1500 }
1501 else
1502 {
1503 len = strlen (file) + strlen (request->directory) + 17;
1504 tempstr = g_malloc (len + 1);
1505 strcpy (tempstr + 8, request->directory);
1506 strcat (tempstr + 8, "/");
1507 strcat (tempstr + 8, file);
1508 }
1509
1510 num = htonl (params->id++);
1511 memcpy (tempstr, &num, 4);
1512
1513 num = htonl (len - 16);
1514 memcpy (tempstr + 4, &num, 4);
1515 1504
1516 num = htonl (SSH_FILEXFER_ATTR_PERMISSIONS); 1505 num = htonl (SSH_FILEXFER_ATTR_PERMISSIONS);
1517 memcpy (tempstr + len - 8, &num, 4); 1506 memcpy (endpos, &num, 4);
1518 1507
1519 g_snprintf (buf, sizeof (buf), "%d", mode); 1508 g_snprintf (buf, sizeof (buf), "%d", mode);
1520 num = htonl (strtol (buf, NULL, 8)); 1509 num = htonl (strtol (buf, NULL, 8));
1521 memcpy (tempstr + len - 4, &num, 4); 1510 memcpy (endpos + 4, &num, 4);
1522 1511
1523 if (sshv2_send_command (request, SSH_FXP_SETSTAT, tempstr, len) < 0) 1512 ret = sshv2_send_command (request, SSH_FXP_SETSTAT, tempstr, len);
1524 { 1513
1525 g_free (tempstr);
1526 return (GFTP_ERETRYABLE);
1527 }
1528 g_free (tempstr); 1514 g_free (tempstr);
1515 if (ret < 0)
1516 return (ret);
1529 1517
1530 memset (&message, 0, sizeof (message)); 1518 memset (&message, 0, sizeof (message));
1531 if ((ret = sshv2_read_response (request, &message, -1)) < 0) 1519 if ((ret = sshv2_read_response (request, &message, -1)) < 0)
1532 return (ret); 1520 return (ret);
1533 1521
1545 sshv2_mkdir (gftp_request * request, const char *newdir) 1533 sshv2_mkdir (gftp_request * request, const char *newdir)
1546 { 1534 {
1547 sshv2_params * params; 1535 sshv2_params * params;
1548 sshv2_message message; 1536 sshv2_message message;
1549 char *tempstr; 1537 char *tempstr;
1550 gint32 num;
1551 size_t len; 1538 size_t len;
1552 int ret; 1539 int ret;
1553 1540
1554 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1541 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1555 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); 1542 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL);
1556 g_return_val_if_fail (newdir != NULL, GFTP_EFATAL); 1543 g_return_val_if_fail (newdir != NULL, GFTP_EFATAL);
1557 1544
1558 params = request->protocol_data; 1545 params = request->protocol_data;
1559 1546
1560 if (*newdir == '/') 1547 len = 4; /* For attributes */
1561 { 1548 tempstr = sshv2_initialize_string_with_path (request, newdir, &len, NULL);
1562 len = strlen (newdir) + 12; 1549
1563 tempstr = g_malloc (len + 1); 1550 /* No need to set attributes since all characters of the tempstr buffer is
1564 strcpy (tempstr + 8, newdir); 1551 initialized to 0 */
1565 } 1552
1566 else 1553 ret = sshv2_send_command (request, SSH_FXP_MKDIR, tempstr, len);
1567 { 1554
1568 len = strlen (newdir) + strlen (request->directory) + 13;
1569 tempstr = g_malloc (len + 1);
1570 strcpy (tempstr + 8, request->directory);
1571 strcat (tempstr + 8, "/");
1572 strcat (tempstr + 8, newdir);
1573 }
1574
1575 num = htonl (params->id++);
1576 memcpy (tempstr, &num, 4);
1577
1578 num = htonl (len - 12);
1579 memcpy (tempstr + 4, &num, 4);
1580 memset (tempstr + len - 4, 0, 4); /* attributes */
1581
1582 if (sshv2_send_command (request, SSH_FXP_MKDIR, tempstr, len) < 0)
1583 {
1584 g_free (tempstr);
1585 return (GFTP_ERETRYABLE);
1586 }
1587 g_free (tempstr); 1555 g_free (tempstr);
1556 if (ret < 0)
1557 return (ret);
1588 1558
1589 memset (&message, 0, sizeof (message)); 1559 memset (&message, 0, sizeof (message));
1590 if ((ret = sshv2_read_response (request, &message, -1)) < 0) 1560 if ((ret = sshv2_read_response (request, &message, -1)) < 0)
1591 return (ret); 1561 return (ret);
1592 1562
1602 1572
1603 static int 1573 static int
1604 sshv2_rename (gftp_request * request, const char *oldname, const char *newname) 1574 sshv2_rename (gftp_request * request, const char *oldname, const char *newname)
1605 { 1575 {
1606 char *tempstr, *oldstr, *newstr; 1576 char *tempstr, *oldstr, *newstr;
1577 size_t oldlen, newlen, len;
1607 sshv2_params * params; 1578 sshv2_params * params;
1608 sshv2_message message; 1579 sshv2_message message;
1609 size_t oldlen, newlen;
1610 gint32 num;
1611 int ret; 1580 int ret;
1612 1581
1613 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1582 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1614 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); 1583 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL);
1615 g_return_val_if_fail (oldname != NULL, GFTP_EFATAL); 1584 g_return_val_if_fail (oldname != NULL, GFTP_EFATAL);
1616 g_return_val_if_fail (newname != NULL, GFTP_EFATAL); 1585 g_return_val_if_fail (newname != NULL, GFTP_EFATAL);
1617 1586
1618 params = request->protocol_data; 1587 params = request->protocol_data;
1619 1588
1620 if (*oldname == '/') 1589 if (*oldname == '/')
1621 { 1590 oldstr = g_strdup (oldname);
1622 oldlen = strlen (oldname);
1623 oldstr = g_strdup (oldname);
1624 }
1625 else 1591 else
1626 { 1592 oldstr = gftp_build_path (request->directory, oldname, NULL);
1627 oldlen = strlen (request->directory) + strlen (oldname) + 1;
1628 oldstr = gftp_build_path (request->directory, oldname, NULL);
1629 }
1630 1593
1631 if (*newname == '/') 1594 if (*newname == '/')
1632 { 1595 newstr = g_strdup (newname);
1633 newlen = strlen (newname);
1634 newstr = g_strdup (newname);
1635 }
1636 else 1596 else
1637 { 1597 newstr = gftp_build_path (request->directory, newname, NULL);
1638 newlen = strlen (request->directory) + strlen (newname) + 1; 1598
1639 newstr = gftp_build_path (request->directory, newname, NULL); 1599 oldlen = strlen (oldstr);
1640 } 1600 newlen = strlen (newname);
1641 1601
1642 tempstr = g_malloc (oldlen + newlen + 13); 1602 len = oldlen + newlen + 12;
1643 num = htonl (params->id++); 1603 tempstr = sshv2_initialize_string (request, len);
1644 memcpy (tempstr, &num, 4); 1604 sshv2_add_string_to_buf (tempstr + 4, oldstr);
1645 1605 sshv2_add_string_to_buf (tempstr + 8 + oldlen, newstr);
1646 num = htonl (oldlen); 1606
1647 memcpy (tempstr + 4, &num, 4); 1607 g_free (oldstr);
1648 strcpy (tempstr + 8, oldstr); 1608 g_free (newstr);
1649 1609
1650 num = htonl (newlen); 1610 ret = sshv2_send_command (request, SSH_FXP_RENAME, tempstr, len);
1651 memcpy (tempstr + 8 + oldlen, &num, 4); 1611
1652 strcpy (tempstr + 12 + oldlen, newstr);
1653
1654 if (sshv2_send_command (request, SSH_FXP_RENAME, tempstr, oldlen + newlen + 12) < 0)
1655 {
1656 g_free (tempstr);
1657 return (GFTP_ERETRYABLE);
1658 }
1659 g_free (tempstr); 1612 g_free (tempstr);
1613 if (ret < 0)
1614 return (ret);
1660 1615
1661 memset (&message, 0, sizeof (message)); 1616 memset (&message, 0, sizeof (message));
1662 if ((ret = sshv2_read_response (request, &message, -1)) < 0) 1617 if ((ret = sshv2_read_response (request, &message, -1)) < 0)
1663 return (ret); 1618 return (ret);
1664 1619
1673 1628
1674 1629
1675 static int 1630 static int
1676 sshv2_set_file_time (gftp_request * request, const char *file, time_t datetime) 1631 sshv2_set_file_time (gftp_request * request, const char *file, time_t datetime)
1677 { 1632 {
1633 char *tempstr, *endpos;
1678 sshv2_params * params; 1634 sshv2_params * params;
1679 sshv2_message message; 1635 sshv2_message message;
1680 char *tempstr;
1681 gint32 num; 1636 gint32 num;
1682 size_t len; 1637 size_t len;
1683 int ret; 1638 int ret;
1684 1639
1685 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1640 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1686 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); 1641 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL);
1687 g_return_val_if_fail (file != NULL, GFTP_EFATAL); 1642 g_return_val_if_fail (file != NULL, GFTP_EFATAL);
1688 1643
1689 params = request->protocol_data; 1644 params = request->protocol_data;
1690 1645
1691 if (*file == '/') 1646 len = 12; /* For date/time */
1692 { 1647 tempstr = sshv2_initialize_string_with_path (request, file, &len, &endpos);
1693 len = strlen (file) + 20;
1694 tempstr = g_malloc (len + 1);
1695 strcpy (tempstr + 8, file);
1696 }
1697 else
1698 {
1699 len = strlen (file) + strlen (request->directory) + 21;
1700 tempstr = g_malloc (len + 1);
1701 strcpy (tempstr + 8, request->directory);
1702 strcat (tempstr + 8, "/");
1703 strcat (tempstr + 8, file);
1704 }
1705
1706 num = htonl (params->id++);
1707 memcpy (tempstr, &num, 4);
1708
1709 num = htonl (len - 20);
1710 memcpy (tempstr + 4, &num, 4);
1711 1648
1712 num = htonl (SSH_FILEXFER_ATTR_ACMODTIME); 1649 num = htonl (SSH_FILEXFER_ATTR_ACMODTIME);
1713 memcpy (tempstr + len - 12, &num, 4); 1650 memcpy (endpos, &num, 4);
1714 1651
1715 num = htonl (datetime); 1652 num = htonl (datetime);
1716 memcpy (tempstr + len - 8, &num, 4); 1653 memcpy (endpos + 4, &num, 4);
1717 1654 memcpy (endpos + 8, &num, 4);
1718 num = htonl (datetime); 1655
1719 memcpy (tempstr + len - 4, &num, 4); 1656 ret = sshv2_send_command (request, SSH_FXP_SETSTAT, tempstr, len);
1720 1657
1721 if (sshv2_send_command (request, SSH_FXP_SETSTAT, tempstr, len) < 0)
1722 {
1723 g_free (tempstr);
1724 return (GFTP_ERETRYABLE);
1725 }
1726 g_free (tempstr); 1658 g_free (tempstr);
1659 if (ret < 0)
1660 return (ret);
1727 1661
1728 memset (&message, 0, sizeof (message)); 1662 memset (&message, 0, sizeof (message));
1729 if ((ret = sshv2_read_response (request, &message, -1)) < 0) 1663 if ((ret = sshv2_read_response (request, &message, -1)) < 0)
1730 return (ret); 1664 return (ret);
1731 1665
1751 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1685 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1752 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); 1686 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL);
1753 g_return_val_if_fail (file != NULL, GFTP_EFATAL); 1687 g_return_val_if_fail (file != NULL, GFTP_EFATAL);
1754 1688
1755 len = 0; 1689 len = 0;
1756 tempstr = sshv2_initialize_string_with_path (request, file, &len); 1690 tempstr = sshv2_initialize_string_with_path (request, file, &len, NULL);
1757 1691
1758 ret = sshv2_send_command (request, SSH_FXP_STAT, tempstr, len); 1692 ret = sshv2_send_command (request, SSH_FXP_STAT, tempstr, len);
1759 1693
1760 g_free (tempstr); 1694 g_free (tempstr);
1761 if (ret < 0) 1695 if (ret < 0)
1801 1735
1802 static off_t 1736 static off_t
1803 sshv2_get_file (gftp_request * request, const char *file, int fd, 1737 sshv2_get_file (gftp_request * request, const char *file, int fd,
1804 off_t startsize) 1738 off_t startsize)
1805 { 1739 {
1740 char *tempstr, *endpos;
1806 sshv2_params * params; 1741 sshv2_params * params;
1807 sshv2_message message; 1742 sshv2_message message;
1808 char *tempstr, *path; 1743 size_t len;
1809 size_t stlen;
1810 gint32 num; 1744 gint32 num;
1811 int ret; 1745 int ret;
1812 1746
1813 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1747 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1814 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); 1748 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL);
1816 /* fd ignored for this protocol */ 1750 /* fd ignored for this protocol */
1817 1751
1818 params = request->protocol_data; 1752 params = request->protocol_data;
1819 params->offset = startsize; 1753 params->offset = startsize;
1820 1754
1821 if (*file == '/') 1755 len = 8;
1822 { 1756 tempstr = sshv2_initialize_string_with_path (request, file, &len, &endpos);
1823 stlen = strlen (file);
1824 tempstr = g_malloc (stlen + 16);
1825 strcpy (tempstr + 8, file);
1826 }
1827 else
1828 {
1829 path = gftp_build_path (request->directory, file, NULL);
1830 stlen = strlen (path);
1831 tempstr = g_malloc (stlen + 16);
1832 strcpy (tempstr + 8, path);
1833 g_free (path);
1834 }
1835
1836 num = htonl (params->id++);
1837 memcpy (tempstr, &num, 4);
1838
1839 num = htonl (stlen);
1840 memcpy (tempstr + 4, &num, 4);
1841 1757
1842 num = htonl (SSH_FXF_READ); 1758 num = htonl (SSH_FXF_READ);
1843 memcpy (tempstr + 8 + stlen, &num, 4); 1759 memcpy (endpos, &num, 4);
1844 1760
1845 num = 0; 1761 ret = sshv2_send_command (request, SSH_FXP_OPEN, tempstr, len);
1846 memcpy (tempstr + 12 + stlen, &num, 4);
1847
1848 if (sshv2_send_command (request, SSH_FXP_OPEN, tempstr, stlen + 16) < 0)
1849 {
1850 g_free (tempstr);
1851 return (GFTP_ERETRYABLE);
1852 }
1853 1762
1854 g_free (tempstr); 1763 g_free (tempstr);
1855 memset (&message, 0, sizeof (message));
1856 ret = sshv2_read_response (request, &message, -1);
1857 if (ret < 0) 1764 if (ret < 0)
1858 return (ret); 1765 return (ret);
1859 else if (ret == SSH_FXP_STATUS) 1766
1860 { 1767 ret = sshv2_read_status_response (request, &message, -1, SSH_FXP_STATUS,
1861 sshv2_message_free (&message); 1768 SSH_FXP_HANDLE);
1862 return (GFTP_ERETRYABLE); 1769 if (ret < 0)
1863 } 1770 return (ret);
1864 else if (ret != SSH_FXP_HANDLE)
1865 {
1866 request->logging_function (gftp_logging_error, request,
1867 _("Received wrong response from server, disconnecting\n"));
1868 sshv2_message_free (&message);
1869 gftp_disconnect (request);
1870 return (GFTP_ERETRYABLE);
1871 }
1872 1771
1873 if (message.length - 4 > SSH_MAX_HANDLE_SIZE) 1772 if (message.length - 4 > SSH_MAX_HANDLE_SIZE)
1874 { 1773 {
1875 request->logging_function (gftp_logging_error, request, 1774 request->logging_function (gftp_logging_error, request,
1876 _("Error: Message size %d too big from server\n"), 1775 _("Error: Message size %d too big from server\n"),
1892 1791
1893 static int 1792 static int
1894 sshv2_put_file (gftp_request * request, const char *file, int fd, 1793 sshv2_put_file (gftp_request * request, const char *file, int fd,
1895 off_t startsize, off_t totalsize) 1794 off_t startsize, off_t totalsize)
1896 { 1795 {
1796 char *tempstr, *endpos;
1897 sshv2_params * params; 1797 sshv2_params * params;
1898 sshv2_message message; 1798 sshv2_message message;
1899 char *tempstr, *path; 1799 size_t len;
1900 size_t stlen;
1901 gint32 num; 1800 gint32 num;
1902 int ret; 1801 int ret;
1903 1802
1904 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1803 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1905 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); 1804 g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL);
1907 /* fd ignored for this protocol */ 1806 /* fd ignored for this protocol */
1908 1807
1909 params = request->protocol_data; 1808 params = request->protocol_data;
1910 params->offset = startsize; 1809 params->offset = startsize;
1911 1810
1912 if (*file == '/') 1811 len = 8;
1913 { 1812 tempstr = sshv2_initialize_string_with_path (request, file, &len, &endpos);
1914 stlen = strlen (file);
1915 tempstr = g_malloc (stlen + 16);
1916 strcpy (tempstr + 8, file);
1917 }
1918 else
1919 {
1920 path = gftp_build_path (request->directory, file, NULL);
1921 stlen = strlen (path);
1922 tempstr = g_malloc (stlen + 16);
1923 strcpy (tempstr + 8, path);
1924 g_free (path);
1925 }
1926
1927 num = htonl (params->id++);
1928 memcpy (tempstr, &num, 4);
1929
1930 num = htonl (stlen);
1931 memcpy (tempstr + 4, &num, 4);
1932 1813
1933 if (startsize > 0) 1814 if (startsize > 0)
1934 num = htonl (SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_APPEND); 1815 num = htonl (SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_APPEND);
1935 else 1816 else
1936 num = htonl (SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC); 1817 num = htonl (SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC);
1937 memcpy (tempstr + 8 + stlen, &num, 4); 1818 memcpy (endpos, &num, 4);
1938 1819
1939 num = 0; 1820 ret = sshv2_send_command (request, SSH_FXP_OPEN, tempstr, len);
1940 memcpy (tempstr + 12 + stlen, &num, 4);
1941
1942 if (sshv2_send_command (request, SSH_FXP_OPEN, tempstr, stlen + 16) < 0)
1943 {
1944 g_free (tempstr);
1945 return (GFTP_ERETRYABLE);
1946 }
1947 1821
1948 g_free (tempstr); 1822 g_free (tempstr);
1949 memset (&message, 0, sizeof (message));
1950 ret = sshv2_read_response (request, &message, -1);
1951 if (ret < 0) 1823 if (ret < 0)
1952 return (ret); 1824 return (ret);
1953 else if (ret == SSH_FXP_STATUS) 1825
1954 { 1826 ret = sshv2_read_status_response (request, &message, -1, SSH_FXP_STATUS,
1955 sshv2_message_free (&message); 1827 SSH_FXP_HANDLE);
1956 return (GFTP_ERETRYABLE); 1828 if (ret < 0)
1957 } 1829 return (ret);
1958 else if (ret != SSH_FXP_HANDLE)
1959 {
1960 request->logging_function (gftp_logging_error, request,
1961 _("Received wrong response from server, disconnecting\n"));
1962 sshv2_message_free (&message);
1963 gftp_disconnect (request);
1964 return (GFTP_ERETRYABLE);
1965 }
1966 1830
1967 if (message.length - 4 > SSH_MAX_HANDLE_SIZE) 1831 if (message.length - 4 > SSH_MAX_HANDLE_SIZE)
1968 { 1832 {
1969 request->logging_function (gftp_logging_error, request, 1833 request->logging_function (gftp_logging_error, request,
1970 _("Error: Message size %d too big from server\n"), 1834 _("Error: Message size %d too big from server\n"),
2025 #endif 1889 #endif
2026 1890
2027 num = htonl (size); 1891 num = htonl (size);
2028 memcpy (params->read_buffer + params->handle_len + 8, &num, 4); 1892 memcpy (params->read_buffer + params->handle_len + 8, &num, 4);
2029 1893
2030 if (sshv2_send_command (request, SSH_FXP_READ, params->read_buffer, params->handle_len + 12) < 0) 1894 if (sshv2_send_command (request, SSH_FXP_READ, params->read_buffer,
1895 params->handle_len + 12) < 0)
2031 return (GFTP_ERETRYABLE); 1896 return (GFTP_ERETRYABLE);
2032 1897
2033 memset (&message, 0, sizeof (message)); 1898 memset (&message, 0, sizeof (message));
2034 if ((ret = sshv2_read_response (request, &message, -1)) != SSH_FXP_DATA) 1899 if ((ret = sshv2_read_response (request, &message, -1)) != SSH_FXP_DATA)
2035 { 1900 {
2043 if (num != SSH_FX_EOF) 1908 if (num != SSH_FX_EOF)
2044 { 1909 {
2045 request->logging_function (gftp_logging_error, request, 1910 request->logging_function (gftp_logging_error, request,
2046 _("Received wrong response from server, disconnecting\n")); 1911 _("Received wrong response from server, disconnecting\n"));
2047 gftp_disconnect (request); 1912 gftp_disconnect (request);
2048 return (GFTP_ERETRYABLE); 1913 return (GFTP_EFATAL);
2049 } 1914 }
2050 return (0); 1915 return (0);
2051 } 1916 }
2052 1917
2053 memcpy (&num, message.buffer + 4, 4); 1918 memcpy (&num, message.buffer + 4, 4);
2130 { 1995 {
2131 request->logging_function (gftp_logging_error, request, 1996 request->logging_function (gftp_logging_error, request,
2132 _("Received wrong response from server, disconnecting\n")); 1997 _("Received wrong response from server, disconnecting\n"));
2133 sshv2_message_free (&message); 1998 sshv2_message_free (&message);
2134 gftp_disconnect (request); 1999 gftp_disconnect (request);
2135 return (GFTP_ERETRYABLE); 2000 return (GFTP_EFATAL);
2136 } 2001 }
2137 2002
2138 message.pos += 4; 2003 message.pos += 4;
2139 if ((num = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK)) < 0) 2004 if ((num = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK)) < 0)
2140 return (GFTP_ERETRYABLE); 2005 return (GFTP_ERETRYABLE);