ftpcmd.y (51979) | ftpcmd.y (56668) |
---|---|
1/* 2 * Copyright (c) 1985, 1988, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 31 unchanged lines hidden (view full) --- 40 41%{ 42 43#ifndef lint 44#if 0 45static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94"; 46#endif 47static const char rcsid[] = | 1/* 2 * Copyright (c) 1985, 1988, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 31 unchanged lines hidden (view full) --- 40 41%{ 42 43#ifndef lint 44#if 0 45static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94"; 46#endif 47static const char rcsid[] = |
48 "$FreeBSD: head/libexec/ftpd/ftpcmd.y 51979 1999-10-07 08:41:55Z alfred $"; | 48 "$FreeBSD: head/libexec/ftpd/ftpcmd.y 56668 2000-01-27 09:28:38Z shin $"; |
49#endif /* not lint */ 50 51#include <sys/param.h> 52#include <sys/socket.h> 53#include <sys/stat.h> 54 55#include <netinet/in.h> 56#include <arpa/ftp.h> 57 58#include <ctype.h> 59#include <errno.h> 60#include <glob.h> | 49#endif /* not lint */ 50 51#include <sys/param.h> 52#include <sys/socket.h> 53#include <sys/stat.h> 54 55#include <netinet/in.h> 56#include <arpa/ftp.h> 57 58#include <ctype.h> 59#include <errno.h> 60#include <glob.h> |
61#include <netdb.h> |
|
61#include <pwd.h> 62#include <setjmp.h> 63#include <signal.h> 64#include <stdio.h> 65#include <stdlib.h> 66#include <string.h> 67#include <syslog.h> 68#include <time.h> 69#include <unistd.h> 70#include <libutil.h> 71 72#include "extern.h" 73 | 62#include <pwd.h> 63#include <setjmp.h> 64#include <signal.h> 65#include <stdio.h> 66#include <stdlib.h> 67#include <string.h> 68#include <syslog.h> 69#include <time.h> 70#include <unistd.h> 71#include <libutil.h> 72 73#include "extern.h" 74 |
74extern struct sockaddr_in data_dest, his_addr; | 75extern union sockunion data_dest, his_addr; |
75extern int logged_in; 76extern struct passwd *pw; 77extern int guest; 78extern int paranoid; 79extern int logging; 80extern int type; 81extern int form; 82extern int debug; --- 10 unchanged lines hidden (view full) --- 93off_t restart_point; 94 95static int cmd_type; 96static int cmd_form; 97static int cmd_bytesz; 98char cbuf[512]; 99char *fromname; 100 | 76extern int logged_in; 77extern struct passwd *pw; 78extern int guest; 79extern int paranoid; 80extern int logging; 81extern int type; 82extern int form; 83extern int debug; --- 10 unchanged lines hidden (view full) --- 94off_t restart_point; 95 96static int cmd_type; 97static int cmd_form; 98static int cmd_bytesz; 99char cbuf[512]; 100char *fromname; 101 |
102extern int epsvall; 103 |
|
101%} 102 103%union { 104 int i; 105 char *s; 106} 107 108%token 109 A B C E F I 110 L N P R S T | 104%} 105 106%union { 107 int i; 108 char *s; 109} 110 111%token 112 A B C E F I 113 L N P R S T |
114 ALL |
|
111 112 SP CRLF COMMA 113 114 USER PASS ACCT REIN QUIT PORT 115 PASV TYPE STRU MODE RETR STOR 116 APPE MLFL MAIL MSND MSOM MSAM 117 MRSQ MRCP ALLO REST RNFR RNTO 118 ABOR DELE CWD LIST NLST SITE 119 STAT HELP NOOP MKD RMD PWD 120 CDUP STOU SMNT SYST SIZE MDTM | 115 116 SP CRLF COMMA 117 118 USER PASS ACCT REIN QUIT PORT 119 PASV TYPE STRU MODE RETR STOR 120 APPE MLFL MAIL MSND MSOM MSAM 121 MRSQ MRCP ALLO REST RNFR RNTO 122 ABOR DELE CWD LIST NLST SITE 123 STAT HELP NOOP MKD RMD PWD 124 CDUP STOU SMNT SYST SIZE MDTM |
125 LPRT LPSV EPRT EPSV |
|
121 122 UMASK IDLE CHMOD 123 124 LEXERR 125 126%token <s> STRING 127%token <i> NUMBER 128 129%type <i> check_login octal_number byte_size 130%type <i> struct_code mode_code type_code form_code | 126 127 UMASK IDLE CHMOD 128 129 LEXERR 130 131%token <s> STRING 132%token <i> NUMBER 133 134%type <i> check_login octal_number byte_size 135%type <i> struct_code mode_code type_code form_code |
131%type | 136%type <s> pathstring pathname password username ext_arg 137%type <s> ALL |
132 133%start cmd_list 134 135%% 136 137cmd_list 138 : /* empty */ 139 | cmd_list cmd --- 12 unchanged lines hidden (view full) --- 152 } 153 | PASS SP password CRLF 154 { 155 pass($3); 156 free($3); 157 } 158 | PORT check_login SP host_port CRLF 159 { | 138 139%start cmd_list 140 141%% 142 143cmd_list 144 : /* empty */ 145 | cmd_list cmd --- 12 unchanged lines hidden (view full) --- 158 } 159 | PASS SP password CRLF 160 { 161 pass($3); 162 free($3); 163 } 164 | PORT check_login SP host_port CRLF 165 { |
160 if ($2) { 161 if (paranoid && 162 ((ntohs(data_dest.sin_port) < 163 IPPORT_RESERVED) || 164 memcmp(&data_dest.sin_addr, 165 &his_addr.sin_addr, 166 sizeof(data_dest.sin_addr)))) { 167 usedefault = 1; | 166 if (epsvall) { 167 reply(501, "no PORT allowed after EPSV ALL"); 168 goto port_done; 169 } 170 if (!$2) 171 goto port_done; 172 if (port_check("PORT") == 1) 173 goto port_done; 174#ifdef INET6 175 if ((his_addr.su_family != AF_INET6 || 176 !IN6_IS_ADDR_V4MAPPED(&his_addr.su_sin6.sin6_addr))) { 177 /* shoud never happen */ 178 usedefault = 1; 179 reply(500, "Invalid address rejected."); 180 goto port_done; 181 } 182 port_check_v6("pcmd"); 183#endif 184 port_done: 185 } 186 | LPRT check_login SP host_long_port CRLF 187 { 188 if (epsvall) { 189 reply(501, "no LPRT allowed after EPSV ALL"); 190 goto lprt_done; 191 } 192 if (!$2) 193 goto lprt_done; 194 if (port_check("LPRT") == 1) 195 goto lprt_done; 196#ifdef INET6 197 if (his_addr.su_family != AF_INET6) { 198 usedefault = 1; 199 reply(500, "Invalid address rejected."); 200 goto lprt_done; 201 } 202 if (port_check_v6("LPRT") == 1) 203 goto lprt_done; 204#endif 205 lprt_done: 206 } 207 | EPRT check_login SP STRING CRLF 208 { 209 char delim; 210 char *tmp = NULL; 211 char *p, *q; 212 char *result[3]; 213 struct addrinfo hints; 214 struct addrinfo *res; 215 int i; 216 217 if (epsvall) { 218 reply(501, "no EPRT allowed after EPSV ALL"); 219 goto eprt_done; 220 } 221 if (!$2) 222 goto eprt_done; 223 224 memset(&data_dest, 0, sizeof(data_dest)); 225 tmp = strdup($4); 226 if (debug) 227 syslog(LOG_DEBUG, "%s", tmp); 228 if (!tmp) { 229 fatal("not enough core"); 230 /*NOTREACHED*/ 231 } 232 p = tmp; 233 delim = p[0]; 234 p++; 235 memset(result, 0, sizeof(result)); 236 for (i = 0; i < 3; i++) { 237 q = strchr(p, delim); 238 if (!q || *q != delim) { 239 parsefail: |
168 reply(500, | 240 reply(500, |
169 "Illegal PORT range rejected."); 170 } else { 171 usedefault = 0; 172 if (pdata >= 0) { 173 (void) close(pdata); 174 pdata = -1; 175 } 176 reply(200, "PORT command successful."); | 241 "Invalid argument, rejected."); 242 if (tmp) 243 free(tmp); 244 usedefault = 1; 245 goto eprt_done; |
177 } | 246 } |
247 *q++ = '\0'; 248 result[i] = p; 249 if (debug) 250 syslog(LOG_DEBUG, "%d: %s", i, p); 251 p = q; |
|
178 } | 252 } |
253 254 /* some more sanity check */ 255 p = result[0]; 256 while (*p) { 257 if (!isdigit(*p)) 258 goto parsefail; 259 p++; 260 } 261 p = result[2]; 262 while (*p) { 263 if (!isdigit(*p)) 264 goto parsefail; 265 p++; 266 } 267 268 /* grab address */ 269 memset(&hints, 0, sizeof(hints)); 270 if (atoi(result[0]) == 1) 271 hints.ai_family = PF_INET; 272#ifdef INET6 273 else if (atoi(result[0]) == 2) 274 hints.ai_family = PF_INET6; 275#endif 276 else 277 hints.ai_family = PF_UNSPEC; /*XXX*/ 278 hints.ai_socktype = SOCK_STREAM; 279 i = getaddrinfo(result[1], result[2], &hints, &res); 280 if (i) 281 goto parsefail; 282 memcpy(&data_dest, res->ai_addr, res->ai_addrlen); 283#ifdef INET6 284 if (his_addr.su_family == AF_INET6 285 && data_dest.su_family == AF_INET6) { 286 /* XXX more sanity checks! */ 287 data_dest.su_sin6.sin6_scope_id = 288 his_addr.su_sin6.sin6_scope_id; 289 } 290#endif 291 free(tmp); 292 tmp = NULL; 293 294 if (port_check("EPRT") == 1) 295 goto eprt_done; 296#ifdef INET6 297 if (his_addr.su_family != AF_INET6) { 298 usedefault = 1; 299 reply(500, "Invalid address rejected."); 300 goto eprt_done; 301 } 302 if (port_check_v6("EPRT") == 1) 303 goto eprt_done; 304#endif 305 eprt_done:; |
|
179 } 180 | PASV check_login CRLF 181 { | 306 } 307 | PASV check_login CRLF 308 { |
182 if ($2) | 309 if (epsvall) 310 reply(501, "no PASV allowed after EPSV ALL"); 311 else if ($2) |
183 passive(); 184 } | 312 passive(); 313 } |
314 | LPSV check_login CRLF 315 { 316 if (epsvall) 317 reply(501, "no LPSV allowed after EPSV ALL"); 318 else if ($2) 319 long_passive("LPSV", PF_UNSPEC); 320 } 321 | EPSV check_login SP NUMBER CRLF 322 { 323 if ($2) { 324 int pf; 325 switch ($4) { 326 case 1: 327 pf = PF_INET; 328 break; 329#ifdef INET6 330 case 2: 331 pf = PF_INET6; 332 break; 333#endif 334 default: 335 pf = -1; /*junk value*/ 336 break; 337 } 338 long_passive("EPSV", pf); 339 } 340 } 341 | EPSV check_login SP ALL CRLF 342 { 343 if ($2) { 344 reply(200, 345 "EPSV ALL command successful."); 346 epsvall++; 347 } 348 } 349 | EPSV check_login CRLF 350 { 351 if ($2) 352 long_passive("EPSV", PF_UNSPEC); 353 } |
|
185 | TYPE SP type_code CRLF 186 { 187 switch (cmd_type) { 188 189 case TYPE_A: 190 if (cmd_form == FORM_N) { 191 reply(200, "Type set to A."); 192 type = cmd_type; --- 378 unchanged lines hidden (view full) --- 571 ; 572 573host_port 574 : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA 575 NUMBER COMMA NUMBER 576 { 577 char *a, *p; 578 | 354 | TYPE SP type_code CRLF 355 { 356 switch (cmd_type) { 357 358 case TYPE_A: 359 if (cmd_form == FORM_N) { 360 reply(200, "Type set to A."); 361 type = cmd_type; --- 378 unchanged lines hidden (view full) --- 740 ; 741 742host_port 743 : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA 744 NUMBER COMMA NUMBER 745 { 746 char *a, *p; 747 |
579 data_dest.sin_len = sizeof(struct sockaddr_in); 580 data_dest.sin_family = AF_INET; 581 p = (char *)&data_dest.sin_port; | 748 data_dest.su_len = sizeof(struct sockaddr_in); 749 data_dest.su_family = AF_INET; 750 p = (char *)&data_dest.su_sin.sin_port; |
582 p[0] = $9; p[1] = $11; | 751 p[0] = $9; p[1] = $11; |
583 a = (char *)&data_dest.sin_addr; | 752 a = (char *)&data_dest.su_sin.sin_addr; |
584 a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7; 585 } 586 ; 587 | 753 a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7; 754 } 755 ; 756 |
757host_long_port 758 : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA 759 NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA 760 NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA 761 NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA 762 NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA 763 NUMBER 764 { 765 char *a, *p; 766 767 memset(&data_dest, 0, sizeof(data_dest)); 768 data_dest.su_len = sizeof(struct sockaddr_in6); 769 data_dest.su_family = AF_INET6; 770 p = (char *)&data_dest.su_port; 771 p[0] = $39; p[1] = $41; 772 a = (char *)&data_dest.su_sin6.sin6_addr; 773 a[0] = $5; a[1] = $7; a[2] = $9; a[3] = $11; 774 a[4] = $13; a[5] = $15; a[6] = $17; a[7] = $19; 775 a[8] = $21; a[9] = $23; a[10] = $25; a[11] = $27; 776 a[12] = $29; a[13] = $31; a[14] = $33; a[15] = $35; 777 if (his_addr.su_family == AF_INET6) { 778 /* XXX more sanity checks! */ 779 data_dest.su_sin6.sin6_scope_id = 780 his_addr.su_sin6.sin6_scope_id; 781 } 782 if ($1 != 6 || $3 != 16 || $37 != 2) 783 memset(&data_dest, 0, sizeof(data_dest)); 784 } 785 | NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA 786 NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA 787 NUMBER 788 { 789 char *a, *p; 790 791 memset(&data_dest, 0, sizeof(data_dest)); 792 data_dest.su_sin.sin_len = sizeof(struct sockaddr_in); 793 data_dest.su_family = AF_INET; 794 p = (char *)&data_dest.su_port; 795 p[0] = $15; p[1] = $17; 796 a = (char *)&data_dest.su_sin.sin_addr; 797 a[0] = $5; a[1] = $7; a[2] = $9; a[3] = $11; 798 if ($1 != 4 || $3 != 4 || $13 != 2) 799 memset(&data_dest, 0, sizeof(data_dest)); 800 } 801 ; 802 |
|
588form_code 589 : N 590 { 591 $$ = FORM_N; 592 } 593 | T 594 { 595 $$ = FORM_T; --- 173 unchanged lines hidden (view full) --- 769struct tab cmdtab[] = { /* In order defined in RFC 765 */ 770 { "USER", USER, STR1, 1, "<sp> username" }, 771 { "PASS", PASS, ZSTR1, 1, "<sp> password" }, 772 { "ACCT", ACCT, STR1, 0, "(specify account)" }, 773 { "SMNT", SMNT, ARGS, 0, "(structure mount)" }, 774 { "REIN", REIN, ARGS, 0, "(reinitialize server state)" }, 775 { "QUIT", QUIT, ARGS, 1, "(terminate service)", }, 776 { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" }, | 803form_code 804 : N 805 { 806 $$ = FORM_N; 807 } 808 | T 809 { 810 $$ = FORM_T; --- 173 unchanged lines hidden (view full) --- 984struct tab cmdtab[] = { /* In order defined in RFC 765 */ 985 { "USER", USER, STR1, 1, "<sp> username" }, 986 { "PASS", PASS, ZSTR1, 1, "<sp> password" }, 987 { "ACCT", ACCT, STR1, 0, "(specify account)" }, 988 { "SMNT", SMNT, ARGS, 0, "(structure mount)" }, 989 { "REIN", REIN, ARGS, 0, "(reinitialize server state)" }, 990 { "QUIT", QUIT, ARGS, 1, "(terminate service)", }, 991 { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" }, |
992 { "LPRT", LPRT, ARGS, 1, "<sp> af, hal, h1, h2, h3,..., pal, p1, p2..." }, 993 { "EPRT", EPRT, STR1, 1, "<sp> |af|addr|port|" }, |
|
777 { "PASV", PASV, ARGS, 1, "(set server in passive mode)" }, | 994 { "PASV", PASV, ARGS, 1, "(set server in passive mode)" }, |
995 { "LPSV", LPSV, ARGS, 1, "(set server in passive mode)" }, 996 { "EPSV", EPSV, ARGS, 1, "[<sp> af|ALL]" }, |
|
778 { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" }, 779 { "STRU", STRU, ARGS, 1, "(specify file structure)" }, 780 { "MODE", MODE, ARGS, 1, "(specify transfer mode)" }, 781 { "RETR", RETR, STR1, 1, "<sp> file-name" }, 782 { "STOR", STOR, STR1, 1, "<sp> file-name" }, 783 { "APPE", APPE, STR1, 1, "<sp> file-name" }, 784 { "MLFL", MLFL, OSTR, 0, "(mail file)" }, 785 { "MAIL", MAIL, OSTR, 0, "(mail to user)" }, --- 38 unchanged lines hidden (view full) --- 824 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" }, 825 { NULL, 0, 0, 0, 0 } 826}; 827 828static char *copy __P((char *)); 829static void help __P((struct tab *, char *)); 830static struct tab * 831 lookup __P((struct tab *, char *)); | 997 { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" }, 998 { "STRU", STRU, ARGS, 1, "(specify file structure)" }, 999 { "MODE", MODE, ARGS, 1, "(specify transfer mode)" }, 1000 { "RETR", RETR, STR1, 1, "<sp> file-name" }, 1001 { "STOR", STOR, STR1, 1, "<sp> file-name" }, 1002 { "APPE", APPE, STR1, 1, "<sp> file-name" }, 1003 { "MLFL", MLFL, OSTR, 0, "(mail file)" }, 1004 { "MAIL", MAIL, OSTR, 0, "(mail to user)" }, --- 38 unchanged lines hidden (view full) --- 1043 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" }, 1044 { NULL, 0, 0, 0, 0 } 1045}; 1046 1047static char *copy __P((char *)); 1048static void help __P((struct tab *, char *)); 1049static struct tab * 1050 lookup __P((struct tab *, char *)); |
1051static int port_check __P((const char *)); 1052static int port_check_v6 __P((const char *)); |
|
832static void sizecmd __P((char *)); 833static void toolong __P((int)); | 1053static void sizecmd __P((char *)); 1054static void toolong __P((int)); |
1055static void v4map_data_dest __P((void)); |
|
834static int yylex __P((void)); 835 836static struct tab * 837lookup(p, cmd) 838 struct tab *p; 839 char *cmd; 840{ 841 --- 238 unchanged lines hidden (view full) --- 1080 while (isdigit(cbuf[++cpos])) 1081 ; 1082 c = cbuf[cpos]; 1083 cbuf[cpos] = '\0'; 1084 yylval.i = atoi(cp); 1085 cbuf[cpos] = c; 1086 return (NUMBER); 1087 } | 1056static int yylex __P((void)); 1057 1058static struct tab * 1059lookup(p, cmd) 1060 struct tab *p; 1061 char *cmd; 1062{ 1063 --- 238 unchanged lines hidden (view full) --- 1302 while (isdigit(cbuf[++cpos])) 1303 ; 1304 c = cbuf[cpos]; 1305 cbuf[cpos] = '\0'; 1306 yylval.i = atoi(cp); 1307 cbuf[cpos] = c; 1308 return (NUMBER); 1309 } |
1310 if (strncasecmp(&cbuf[cpos], "ALL", 3) == 0 1311 && !isalnum(cbuf[cpos + 3])) { 1312 cpos += 3; 1313 return ALL; 1314 } |
|
1088 switch (cbuf[cpos++]) { 1089 1090 case '\n': 1091 state = CMD; 1092 return (CRLF); 1093 1094 case ' ': 1095 return (SP); --- 188 unchanged lines hidden (view full) --- 1284 (void) fclose(fin); 1285 1286 reply(213, "%qd", count); 1287 break; } 1288 default: 1289 reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]); 1290 } 1291} | 1315 switch (cbuf[cpos++]) { 1316 1317 case '\n': 1318 state = CMD; 1319 return (CRLF); 1320 1321 case ' ': 1322 return (SP); --- 188 unchanged lines hidden (view full) --- 1511 (void) fclose(fin); 1512 1513 reply(213, "%qd", count); 1514 break; } 1515 default: 1516 reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]); 1517 } 1518} |
1519 1520/* Return 1, if port check is done. Return 0, if not yet. */ 1521static int 1522port_check(pcmd) 1523 const char *pcmd; 1524{ 1525 if (his_addr.su_family == AF_INET) { 1526 if (data_dest.su_family != AF_INET) { 1527 usedefault = 1; 1528 reply(500, "Invalid address rejected."); 1529 return 1; 1530 } 1531 if (paranoid && 1532 ((ntohs(data_dest.su_port) < IPPORT_RESERVED) || 1533 memcmp(&data_dest.su_sin.sin_addr, 1534 &his_addr.su_sin.sin_addr, 1535 sizeof(data_dest.su_sin.sin_addr)))) { 1536 usedefault = 1; 1537 reply(500, "Illegal PORT range rejected."); 1538 } else { 1539 usedefault = 0; 1540 if (pdata >= 0) { 1541 (void) close(pdata); 1542 pdata = -1; 1543 } 1544 reply(200, "%s command successful.", pcmd); 1545 } 1546 return 1; 1547 } 1548 return 0; 1549} 1550 1551#ifdef INET6 1552/* Return 1, if port check is done. Return 0, if not yet. */ 1553static int 1554port_check_v6(pcmd) 1555 const char *pcmd; 1556{ 1557 if (his_addr.su_family == AF_INET6) { 1558 if (IN6_IS_ADDR_V4MAPPED(&his_addr.su_sin6.sin6_addr)) 1559 /* Convert data_dest into v4 mapped sockaddr.*/ 1560 v4map_data_dest(); 1561 if (data_dest.su_family != AF_INET6) { 1562 usedefault = 1; 1563 reply(500, "Invalid address rejected."); 1564 return 1; 1565 } 1566 if (paranoid && 1567 ((ntohs(data_dest.su_port) < IPPORT_RESERVED) || 1568 memcmp(&data_dest.su_sin6.sin6_addr, 1569 &his_addr.su_sin6.sin6_addr, 1570 sizeof(data_dest.su_sin6.sin6_addr)))) { 1571 usedefault = 1; 1572 reply(500, "Illegal PORT range rejected."); 1573 } else { 1574 usedefault = 0; 1575 if (pdata >= 0) { 1576 (void) close(pdata); 1577 pdata = -1; 1578 } 1579 reply(200, "%s command successful.", pcmd); 1580 } 1581 return 1; 1582 } 1583 return 0; 1584} 1585 1586static void 1587v4map_data_dest() 1588{ 1589 struct in_addr savedaddr; 1590 int savedport; 1591 1592 if (data_dest.su_family != AF_INET) { 1593 usedefault = 1; 1594 reply(500, "Invalid address rejected."); 1595 return; 1596 } 1597 1598 savedaddr = data_dest.su_sin.sin_addr; 1599 savedport = data_dest.su_port; 1600 1601 memset(&data_dest, 0, sizeof(data_dest)); 1602 data_dest.su_sin6.sin6_len = sizeof(struct sockaddr_in6); 1603 data_dest.su_sin6.sin6_family = AF_INET6; 1604 data_dest.su_sin6.sin6_port = savedport; 1605 memset((caddr_t)&data_dest.su_sin6.sin6_addr.s6_addr[10], 0xff, 2); 1606 memcpy((caddr_t)&data_dest.su_sin6.sin6_addr.s6_addr[12], 1607 (caddr_t)&savedaddr, sizeof(savedaddr)); 1608} 1609#endif |
|