comparison lib/rfc959.c @ 847:14858879916f

2006-11-2 Brian Masney <masneyb@gftp.org> * lib/ftpcommon.h lib/ftps.c lib/rfc959.c - use the encoded filename length to determine how many bytes should be sent in the command to the remote server. Don't use the strlen() function since there may be a NUL character in the filename. ATTENTION INTERNATIONAL USERS: If you have time, can you test the filename encoding in CVS? All of the necessary changes were made to the local, FTP and SSH protocols. Let me know if you see any problems.
author masneyb
date Fri, 03 Nov 2006 03:23:19 +0000
parents 8263cc35c027
children 10e2ce91e26c
comparison
equal deleted inserted replaced
846:77660334b282 847:14858879916f
144 } 144 }
145 145
146 146
147 int 147 int
148 rfc959_send_command (gftp_request * request, const char *command, 148 rfc959_send_command (gftp_request * request, const char *command,
149 int read_response, int dont_try_to_reconnect) 149 ssize_t command_len, int read_response,
150 int dont_try_to_reconnect)
150 { 151 {
151 int ret; 152 int ret;
152 153
153 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 154 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
154 g_return_val_if_fail (command != NULL, GFTP_EFATAL); 155 g_return_val_if_fail (command != NULL, GFTP_EFATAL);
168 { 169 {
169 request->logging_function (gftp_logging_send, request, "%s", 170 request->logging_function (gftp_logging_send, request, "%s",
170 command); 171 command);
171 } 172 }
172 173
173 if ((ret = request->write_function (request, command, strlen (command), 174 if (command_len == -1)
175 command_len = strlen (command);
176
177 if ((ret = request->write_function (request, command, command_len,
174 request->datafd)) < 0) 178 request->datafd)) < 0)
175 return (ret); 179 return (ret);
176 180
177 if (read_response) 181 if (read_response)
178 { 182 {
181 { 185 {
182 ret = gftp_connect (request); 186 ret = gftp_connect (request);
183 if (ret < 0) 187 if (ret < 0)
184 return (ret); 188 return (ret);
185 189
186 return (rfc959_send_command (request, command, 1, 1)); 190 return (rfc959_send_command (request, command, command_len, 1, 1));
187 } 191 }
188 else 192 else
189 return (ret); 193 return (ret);
190 } 194 }
191 else 195 else
196 rfc959_generate_and_send_command (gftp_request * request, const char *command, 200 rfc959_generate_and_send_command (gftp_request * request, const char *command,
197 const char *argument, int read_response, 201 const char *argument, int read_response,
198 int dont_try_to_reconnect) 202 int dont_try_to_reconnect)
199 { 203 {
200 char *tempstr, *utf8; 204 char *tempstr, *utf8;
201 size_t destlen; 205 size_t len;
202 int resp; 206 int resp;
203 207
204 if (argument != NULL) 208 if (argument != NULL)
205 { 209 {
206 utf8 = gftp_filename_from_utf8 (request, argument, &destlen); 210 utf8 = gftp_filename_from_utf8 (request, argument, &len);
207 if (utf8 != NULL) 211 if (utf8 != NULL)
208 { 212 {
209 tempstr = g_strconcat (command, " ", utf8, "\r\n", NULL); 213 tempstr = g_strconcat (command, " ", utf8, "\r\n", NULL);
210 g_free (utf8); 214 g_free (utf8);
211 } 215 }
212 tempstr = g_strconcat (command, " ", argument, "\r\n", NULL); 216 else
213 } 217 {
214 else 218 tempstr = g_strconcat (command, " ", argument, "\r\n", NULL);
215 tempstr = g_strconcat (command, "\r\n", NULL); 219 len = strlen (argument);
216 220 }
217 resp = rfc959_send_command (request, tempstr, read_response, 221
222 len += strlen (command) + 3;
223 }
224 else
225 {
226 tempstr = g_strconcat (command, "\r\n", NULL);
227 len = strlen (command) + 2;
228 }
229
230 resp = rfc959_send_command (request, tempstr, len, read_response,
218 dont_try_to_reconnect); 231 dont_try_to_reconnect);
219 g_free (tempstr); 232 g_free (tempstr);
220 return (resp); 233 return (resp);
221 } 234 }
222 235
352 { 365 {
353 char *pos, *dir, *utf8; 366 char *pos, *dir, *utf8;
354 size_t destlen; 367 size_t destlen;
355 int ret; 368 int ret;
356 369
357 ret = rfc959_send_command (request, "PWD\r\n", 1, 0); 370 ret = rfc959_send_command (request, "PWD\r\n", -1, 1, 0);
358 if (ret < 0) 371 if (ret < 0)
359 return (ret); 372 return (ret);
360 else if (ret != '2') 373 else if (ret != '2')
361 { 374 {
362 request->logging_function (gftp_logging_error, request, 375 request->logging_function (gftp_logging_error, request,
408 421
409 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 422 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
410 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); 423 g_return_val_if_fail (directory != NULL, GFTP_EFATAL);
411 424
412 if (strcmp (directory, "..") == 0) 425 if (strcmp (directory, "..") == 0)
413 ret = rfc959_send_command (request, "CDUP\r\n", 1, 0); 426 ret = rfc959_send_command (request, "CDUP\r\n", -1, 1, 0);
414 else 427 else
415 ret = rfc959_generate_and_send_command (request, "CWD", directory, 1, 0); 428 ret = rfc959_generate_and_send_command (request, "CWD", directory, 1, 0);
416 429
417 if (ret < 0) 430 if (ret < 0)
418 return (ret); 431 return (ret);
433 char *stpos, *endpos; 446 char *stpos, *endpos;
434 447
435 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 448 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
436 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); 449 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL);
437 450
438 ret = rfc959_send_command (request, "SYST\r\n", 1, 0); 451 ret = rfc959_send_command (request, "SYST\r\n", -1, 1, 0);
439 452
440 if (ret < 0) 453 if (ret < 0)
441 return (ret); 454 return (ret);
442 else if (ret != '2') 455 else if (ret != '2')
443 return (GFTP_ERETRYABLE); 456 return (GFTP_ERETRYABLE);
546 if (*endpos == '\n' || *endpos == '\0') 559 if (*endpos == '\n' || *endpos == '\0')
547 { 560 {
548 tempchar = *(endpos + 1); 561 tempchar = *(endpos + 1);
549 if (*endpos != '\0') 562 if (*endpos != '\0')
550 *(endpos + 1) = '\0'; 563 *(endpos + 1) = '\0';
551 if ((resp = rfc959_send_command (request, startpos, 1, 0)) < 0) 564 if ((resp = rfc959_send_command (request, startpos, -1, 1, 0)) < 0)
552 return (resp); 565 return (resp);
553 if (*endpos != '\0') 566 if (*endpos != '\0')
554 *(endpos + 1) = tempchar; 567 *(endpos + 1) = tempchar;
555 else 568 else
556 break; 569 break;
607 { 620 {
608 tempstr = "TYPE I\r\n"; 621 tempstr = "TYPE I\r\n";
609 parms->is_ascii_transfer = 0; 622 parms->is_ascii_transfer = 0;
610 } 623 }
611 624
612 if ((ret = rfc959_send_command (request, tempstr, 1, 0)) < 0) 625 if ((ret = rfc959_send_command (request, tempstr, -1, 1, 0)) < 0)
613 return (ret); 626 return (ret);
614 627
615 ret = -1; 628 ret = -1;
616 if (request->directory != NULL && *request->directory != '\0') 629 if (request->directory != NULL && *request->directory != '\0')
617 { 630 {
705 data_addr.sin_family = AF_INET; 718 data_addr.sin_family = AF_INET;
706 719
707 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); 720 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer);
708 if (passive_transfer) 721 if (passive_transfer)
709 { 722 {
710 resp = rfc959_send_command (request, "PASV\r\n", 1, 1); 723 resp = rfc959_send_command (request, "PASV\r\n", -1, 1, 1);
711 if (resp < 0) 724 if (resp < 0)
712 return (resp); 725 return (resp);
713 else if (resp != '2') 726 else if (resp != '2')
714 { 727 {
715 gftp_set_request_option (request, "passive_transfer", 728 gftp_set_request_option (request, "passive_transfer",
824 pos1 = (char *) &data_addr.sin_port; 837 pos1 = (char *) &data_addr.sin_port;
825 command = g_strdup_printf ("PORT %u,%u,%u,%u,%u,%u\r\n", 838 command = g_strdup_printf ("PORT %u,%u,%u,%u,%u,%u\r\n",
826 pos[0] & 0xff, pos[1] & 0xff, pos[2] & 0xff, 839 pos[0] & 0xff, pos[1] & 0xff, pos[2] & 0xff,
827 pos[3] & 0xff, pos1[0] & 0xff, 840 pos[3] & 0xff, pos1[0] & 0xff,
828 pos1[1] & 0xff); 841 pos1[1] & 0xff);
829 resp = rfc959_send_command (request, command, 1, 1); 842 resp = rfc959_send_command (request, command, -1, 1, 1);
830 g_free (command); 843 g_free (command);
831 844
832 if (resp < 0) 845 if (resp < 0)
833 return (resp); 846 return (resp);
834 else if (resp != '2') 847 else if (resp != '2')
891 data_addr.sin6_family = AF_INET6; 904 data_addr.sin6_family = AF_INET6;
892 905
893 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); 906 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer);
894 if (passive_transfer) 907 if (passive_transfer)
895 { 908 {
896 resp = rfc959_send_command (request, "EPSV\r\n", 1, 1); 909 resp = rfc959_send_command (request, "EPSV\r\n", -1, 1, 1);
897 if (resp < 0) 910 if (resp < 0)
898 return (resp); 911 return (resp);
899 else if (resp != '2') 912 else if (resp != '2')
900 { 913 {
901 gftp_set_request_option (request, "passive_transfer", 914 gftp_set_request_option (request, "passive_transfer",
983 } 996 }
984 997
985 command = g_strdup_printf ("EPRT |2|%s|%d|\n", buf, 998 command = g_strdup_printf ("EPRT |2|%s|%d|\n", buf,
986 ntohs (data_addr.sin6_port)); 999 ntohs (data_addr.sin6_port));
987 1000
988 resp = rfc959_send_command (request, command, 1, 1); 1001 resp = rfc959_send_command (request, command, -1, 1, 1);
989 g_free (command); 1002 g_free (command);
990 1003
991 if (resp < 0) 1004 if (resp < 0)
992 return (resp); 1005 return (resp);
993 else if (resp != '2') 1006 else if (resp != '2')
1135 { 1148 {
1136 tempstr = "TYPE I\r\n"; 1149 tempstr = "TYPE I\r\n";
1137 parms->is_ascii_transfer = 0; 1150 parms->is_ascii_transfer = 0;
1138 } 1151 }
1139 1152
1140 if ((ret = rfc959_send_command (request, tempstr, 1, 0)) < 0) 1153 if ((ret = rfc959_send_command (request, tempstr, -1, 1, 0)) < 0)
1141 return (ret); 1154 return (ret);
1142 } 1155 }
1143 1156
1144 return (0); 1157 return (0);
1145 } 1158 }
1174 1187
1175 if (startsize > 0) 1188 if (startsize > 0)
1176 { 1189 {
1177 command = g_strdup_printf ("REST " GFTP_OFF_T_PRINTF_MOD "\r\n", 1190 command = g_strdup_printf ("REST " GFTP_OFF_T_PRINTF_MOD "\r\n",
1178 startsize); 1191 startsize);
1179 ret = rfc959_send_command (request, command, 1, 0); 1192 ret = rfc959_send_command (request, command, -1, 1, 0);
1180 g_free (command); 1193 g_free (command);
1181 1194
1182 if (ret < 0) 1195 if (ret < 0)
1183 return (ret); 1196 return (ret);
1184 else if (ret != '3') 1197 else if (ret != '3')
1244 1257
1245 if (startsize > 0) 1258 if (startsize > 0)
1246 { 1259 {
1247 command = g_strdup_printf ("REST " GFTP_OFF_T_PRINTF_MOD "\r\n", 1260 command = g_strdup_printf ("REST " GFTP_OFF_T_PRINTF_MOD "\r\n",
1248 startsize); 1261 startsize);
1249 ret = rfc959_send_command (request, command, 1, 0); 1262 ret = rfc959_send_command (request, command, -1, 1, 0);
1250 g_free (command); 1263 g_free (command);
1251 if (ret < 0) 1264 if (ret < 0)
1252 return (ret); 1265 return (ret);
1253 else if (ret != '3') 1266 else if (ret != '3')
1254 { 1267 {
1289 g_return_val_if_fail (toreq != NULL, GFTP_EFATAL); 1302 g_return_val_if_fail (toreq != NULL, GFTP_EFATAL);
1290 g_return_val_if_fail (tofile != NULL, GFTP_EFATAL); 1303 g_return_val_if_fail (tofile != NULL, GFTP_EFATAL);
1291 g_return_val_if_fail (fromreq->datafd > 0, GFTP_EFATAL); 1304 g_return_val_if_fail (fromreq->datafd > 0, GFTP_EFATAL);
1292 g_return_val_if_fail (toreq->datafd > 0, GFTP_EFATAL); 1305 g_return_val_if_fail (toreq->datafd > 0, GFTP_EFATAL);
1293 1306
1294 if ((ret = rfc959_send_command (fromreq, "PASV\r\n", 1, 0)) < 0) 1307 if ((ret = rfc959_send_command (fromreq, "PASV\r\n", -1, 1, 0)) < 0)
1295 return (ret); 1308 return (ret);
1296 else if (ret != '2') 1309 else if (ret != '2')
1297 return (GFTP_ERETRYABLE); 1310 return (GFTP_ERETRYABLE);
1298 1311
1299 pos = fromreq->last_ftp_response + 4; 1312 pos = fromreq->last_ftp_response + 4;
1307 endpos++; 1320 endpos++;
1308 if (*endpos == ')') 1321 if (*endpos == ')')
1309 *endpos = '\0'; 1322 *endpos = '\0';
1310 1323
1311 tempstr = g_strconcat ("PORT ", pos, "\r\n", NULL); 1324 tempstr = g_strconcat ("PORT ", pos, "\r\n", NULL);
1312 ret = rfc959_send_command (toreq, tempstr, 1, 0); 1325 ret = rfc959_send_command (toreq, tempstr, -1, 1, 0);
1313 g_free (tempstr); 1326 g_free (tempstr);
1314 1327
1315 if (ret < 0) 1328 if (ret < 0)
1316 return (ret); 1329 return (ret);
1317 else if (ret != '2') 1330 else if (ret != '2')
1372 int ret; 1385 int ret;
1373 1386
1374 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1387 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1375 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); 1388 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL);
1376 1389
1377 if ((ret = rfc959_send_command (request, "ABOR\r\n", 0, 0)) < 0) 1390 if ((ret = rfc959_send_command (request, "ABOR\r\n", -1, 0, 0)) < 0)
1378 return (ret); 1391 return (ret);
1379 1392
1380 rfc959_close_data_connection (request); 1393 rfc959_close_data_connection (request);
1381 1394
1382 if (request->datafd > 0) 1395 if (request->datafd > 0)
1410 strcat (parms, show_hidden_files ? "a" : ""); 1423 strcat (parms, show_hidden_files ? "a" : "");
1411 strcat (parms, resolve_symlinks ? "L" : ""); 1424 strcat (parms, resolve_symlinks ? "L" : "");
1412 tempstr = g_strconcat ("LIST", *parms != '\0' ? " -" : "", parms, "\r\n", 1425 tempstr = g_strconcat ("LIST", *parms != '\0' ? " -" : "", parms, "\r\n",
1413 NULL); 1426 NULL);
1414 1427
1415 ret = rfc959_send_command (request, tempstr, 1, 0); 1428 ret = rfc959_send_command (request, tempstr, -1, 1, 0);
1416 g_free (tempstr); 1429 g_free (tempstr);
1417 1430
1418 if (ret < 0) 1431 if (ret < 0)
1419 return (ret); 1432 return (ret);
1420 else if (ret != '1') 1433 else if (ret != '1')
1717 1730
1718 1731
1719 static int 1732 static int
1720 rfc959_chmod (gftp_request * request, const char *file, mode_t mode) 1733 rfc959_chmod (gftp_request * request, const char *file, mode_t mode)
1721 { 1734 {
1722 char *tempstr, *utf8; 1735 char *tempstr, *utf8, *cmd;
1723 size_t destlen; 1736 size_t destlen;
1724 int ret; 1737 int ret;
1725 1738
1726 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1739 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1727 g_return_val_if_fail (file != NULL, GFTP_EFATAL); 1740 g_return_val_if_fail (file != NULL, GFTP_EFATAL);
1734 g_free (utf8); 1747 g_free (utf8);
1735 } 1748 }
1736 else 1749 else
1737 tempstr = g_strdup_printf ("SITE CHMOD %o %s\r\n", mode, file); 1750 tempstr = g_strdup_printf ("SITE CHMOD %o %s\r\n", mode, file);
1738 1751
1739 ret = rfc959_send_command (request, tempstr, 1, 0); 1752 ret = rfc959_send_command (request, tempstr, -1, 1, 0); /* FIXME - add length */
1740 g_free (tempstr); 1753 g_free (tempstr);
1741 1754
1742 if (ret < 0) 1755 if (ret < 0)
1743 return (ret); 1756 return (ret);
1744 else if (ret == '2') 1757 else if (ret == '2')
1750 1763
1751 static int 1764 static int
1752 rfc959_site (gftp_request * request, int specify_site, const char *command) 1765 rfc959_site (gftp_request * request, int specify_site, const char *command)
1753 { 1766 {
1754 char *tempstr, *utf8; 1767 char *tempstr, *utf8;
1755 size_t destlen; 1768 size_t len;
1756 int ret; 1769 int ret;
1757 1770
1758 g_return_val_if_fail (request != NULL, GFTP_EFATAL); 1771 g_return_val_if_fail (request != NULL, GFTP_EFATAL);
1759 g_return_val_if_fail (command != NULL, GFTP_EFATAL); 1772 g_return_val_if_fail (command != NULL, GFTP_EFATAL);
1760 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); 1773 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL);
1761 1774
1762 utf8 = gftp_string_from_utf8 (request, -1, command, &destlen); 1775 utf8 = gftp_string_from_utf8 (request, -1, command, &len);
1763 if (utf8 != NULL) 1776 if (utf8 != NULL)
1764 { 1777 {
1765 if (specify_site) 1778 if (specify_site)
1766 tempstr = g_strconcat ("SITE ", utf8, "\r\n", NULL); 1779 {
1780 len += 7;
1781 tempstr = g_strconcat ("SITE ", utf8, "\r\n", NULL);
1782 }
1767 else 1783 else
1768 tempstr = g_strconcat (utf8, "\r\n", NULL); 1784 {
1785 len += 2;
1786 tempstr = g_strconcat (utf8, "\r\n", NULL);
1787 }
1769 1788
1770 g_free (utf8); 1789 g_free (utf8);
1771 } 1790 }
1772 else 1791 else
1773 { 1792 {
1774 if (specify_site) 1793 if (specify_site)
1775 tempstr = g_strconcat ("SITE ", command, "\r\n", NULL); 1794 {
1795 len = strlen (command) + 7;
1796 tempstr = g_strconcat ("SITE ", command, "\r\n", NULL);
1797 }
1776 else 1798 else
1777 tempstr = g_strconcat (command, "\r\n", NULL); 1799 {
1778 } 1800 len = strlen (command) + 2;
1779 1801 tempstr = g_strconcat (command, "\r\n", NULL);
1780 ret = rfc959_send_command (request, tempstr, 1, 0); 1802 }
1803 }
1804
1805 ret = rfc959_send_command (request, tempstr, len, 1, 0);
1781 g_free (tempstr); 1806 g_free (tempstr);
1782 1807
1783 if (ret < 0) 1808 if (ret < 0)
1784 return (ret); 1809 return (ret);
1785 else if (ret == '2') 1810 else if (ret == '2')