Mercurial > gftp.yaz
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') |