Removed non portable -v flag for rm command.
[uftps.git] / parse_port_argument.c
blob432b07720ca38e10b385f391d0200e0ee5a825a8
1 /*
2 * User FTP Server, Share folders over FTP without being root.
3 * Copyright (C) 2008 Isaac Jurado
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option) any later
8 * version.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 * details.
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "uftps.h"
21 #ifndef __MINGW32__
22 # include <sys/socket.h>
23 # include <arpa/inet.h>
24 #endif
25 #include <stdlib.h>
26 #include <string.h>
28 /* This is needed by Solaris */
29 #ifndef INADDR_NONE
30 # define INADDR_NONE -1
31 #endif
35 * Parse a PORT argument and convert it to a internet address structure.
36 * Returns -1 when a parsing error occurs.
38 * The argument has the syntax "h1,h2,h3,h4,p1,p2". First, we need to split IP
39 * and port information "h1.h2.h3.h4\0p1,p2" (two strings). The IP string is
40 * finally parsed by inet_addr() into a 'in_addr_t' value. Finally, the port
41 * number is obtained as p1 * 256 + p2 and translated to network byte ordering
42 * with htons().
44 void parse_port_argument (void)
46 int commas, port, i, j;
47 struct sockaddr_in sai;
49 if (SS.arg == NULL)
51 warning("PORT without argument");
52 reply_c("501 Argument required.\r\n");
53 return;
56 /* "h1,h2,h3,h4,p1,p2" ==> "h1.h2.h3.h4" "p1,p2" */
57 i = 0;
58 commas = 0;
59 while (commas < 4)
61 if (SS.arg[i] == '\0')
63 warning("PORT invalid parameter '%s'", SS.arg);
64 reply_c("501 Invalid PORT parameter.\r\n");
65 return;
68 if (SS.arg[i] == ',')
70 commas++;
71 SS.arg[i] = '.';
73 i++;
75 SS.arg[i - 1] = '\0';
77 /* "h1.h2.h3.h4" ==> struct in_addr */
78 sai.sin_addr.s_addr = inet_addr(SS.arg);
79 if (sai.sin_addr.s_addr == INADDR_NONE)
81 error("PORT Translating IP '%s'", SS.arg);
82 reply_c("501 Invalid PORT parameter.\r\n");
83 return;
85 /* Check if destination IP is the same as the client's */
86 if (sai.sin_addr.s_addr != SS.client_address.sin_addr.s_addr)
88 warning("PORT IP %s is not the same as the client's", SS.arg);
89 reply_c("501 Invalid PORT parameter.\r\n");
90 return;
93 /* "p1,p2" ==> int (port number) */
94 j = i;
95 while (SS.arg[j] != ',')
96 j++;
97 SS.arg[j] = '\0';
98 port = atoi(&SS.arg[i]) * 256 + atoi(&SS.arg[j + 1]);
100 /* Save PORT information for later use when opening the data channel */
101 memset(&SS.port_destination, 0, sizeof(struct sockaddr_in));
102 SS.port_destination.sin_family = AF_INET;
103 SS.port_destination.sin_addr = sai.sin_addr;
104 SS.port_destination.sin_port = htons(port & 0x00FFFF);
106 SS.mode = ACTIVE_MODE;
107 debug("PORT parsing results %s:%d\n", SS.arg, port & 0x00FFFF);
108 reply_c("200 PORT Command OK.\r\n");