1#include "config.h" 2#include <errno.h> 3#include <stdio.h> 4#include <stdlib.h> 5#include <stdarg.h> 6#define __USE_GNU 7#include <unistd.h> 8#ifdef HAVE_SYS_TYPES_H 9#include <sys/types.h> 10#endif 11#ifdef HAVE_SYS_STAT_H 12#include <sys/stat.h> 13#endif 14#ifdef HAVE_SYS_SOCKET_H 15#include <sys/socket.h> 16#endif 17#ifdef HAVE_ASM_SOCKET_H 18#include <asm/socket.h> 19#endif 20#ifdef HAVE_NETINET_IN_H 21#include <netinet/in.h> 22#endif 23#ifdef HAVE_ARPA_INET_H 24#include <arpa/inet.h> 25#endif 26#ifdef HAVE_SYS_TIME_H 27#include <sys/time.h> 28#endif 29#ifdef HAVE_TIME_H 30#include <time.h> 31#endif 32#include <fcntl.h> 33#include <string.h> 34#ifdef HAVE_WAIT_H 35# include <wait.h> 36#else 37# ifdef HAVE_SYS_WAIT_H 38# include <sys/wait.h> 39# endif 40#endif 41 42#include <string.h> /* for strncpy */ 43#include <sys/types.h> 44#include <sys/socket.h> 45#include <sys/ioctl.h> 46#include <netinet/in.h> 47#include <net/if.h> 48 49#include "mystring.h" 50#include "login.h" 51#include "logging.h" 52#include "dirlist.h" 53#include "options.h" 54#include "main.h" 55#include "targzip.h" 56#include "cwd.h" 57#include "bftpdutmp.h" 58 59#ifdef HAVE_ZLIB_H 60#include <zlib.h> 61#else 62#undef WANT_GZIP 63#endif 64 65int state = STATE_CONNECTED; 66char user[USERLEN + 1]; 67struct sockaddr_in sa; 68char pasv = 0; 69int sock; 70int pasvsock; 71char *philename = NULL; 72int offset = 0; 73short int xfertype = TYPE_BINARY; 74int ratio_send = 1, ratio_recv = 1; 75long unsigned bytes_sent = 0, bytes_recvd = 0; 76int epsvall = 0; 77int xfer_bufsize; 78 79 80void control_printf(char success, char *format, ...) 81{ 82 char buffer[256]; 83 va_list val; 84 va_start(val, format); 85 vsnprintf(buffer, sizeof(buffer), format, val); 86 va_end(val); 87 /* Foxconn modified start pling 06/29/2010 */ 88 /* Fix Chrome V4.0.249.78 FTP issue: the \r\n needs to appear 89 * immediately after the response. 90 */ 91#if 0 92 fprintf(stderr, "%s\r\n", buffer); 93#endif 94 strcat(buffer, "\r\n"); 95 fprintf(stderr, "%s", buffer); 96 /* Foxconn modified end pling 06/29/2010 */ 97 replace(buffer, "\r", ""); 98 bftpd_statuslog(3, success, "%s", buffer); 99} 100 101void new_umask() 102{ 103 int um; 104 char *foo = config_getoption("UMASK"); 105 if (!foo[0]) 106 um = 022; 107 else 108 um = strtoul(foo, NULL, 8); 109 umask(um); 110} 111 112void prepare_sock(int sock) 113{ 114 int on = 1; 115#ifdef TCP_NODELAY 116 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &on, sizeof(on)); 117#endif 118#ifdef TCP_NOPUSH 119 setsockopt(sock, IPPROTO_TCP, TCP_NOPUSH, (void *) &on, sizeof(on)); 120#endif 121#ifdef SO_REUSEADDR 122 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)); 123#endif 124#ifdef SO_REUSEPORT 125 setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void *) &on, sizeof(on)); 126#endif 127#ifdef SO_SNDBUF 128/* Foxconn modified start, Jonathan 10/14/2011 */ 129#if 1 130 /* because open 15 sessions to downlod that caused system crash, set smaller sending buffer */ 131 on = 1024*128; 132#else 133 on = 1024*1024*4; /* wklin modified, 11/19/2009 */ 134#endif 135/* Foxconn modified end, Jonathan 10/14/2011 */ 136 setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *) &on, sizeof(on)); 137 on = 65536*10; /* wklin modified, 11/19/2009 */ 138 setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *) &on, sizeof(on)); // Foxconn added pling 06/19/2009 139#endif 140} 141 142int dataconn() 143{ 144 struct sockaddr foo; 145 struct sockaddr_in local; 146 socklen_t namelen = sizeof(foo); 147 int curuid = geteuid(); 148 149 memset(&foo, 0, sizeof(foo)); 150 memset(&local, 0, sizeof(local)); 151 152 if (pasv) { 153 sock = accept(pasvsock, (struct sockaddr *) &foo, (socklen_t *) &namelen); 154 if (sock == -1) { 155 control_printf(SL_FAILURE, "425-Unable to accept data connection.\r\n425 %s.", 156 strerror(errno)); 157 return 1; 158 } 159 close(pasvsock); 160 prepare_sock(sock); 161 } else { 162 sock = socket(AF_INET, SOCK_STREAM, 0); 163 prepare_sock(sock); 164 local.sin_addr.s_addr = name.sin_addr.s_addr; 165 local.sin_family = AF_INET; 166 if (!strcasecmp(config_getoption("DATAPORT20"), "yes")) { 167 seteuid(0); 168 local.sin_port = htons(20); 169 } 170 if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) { 171 control_printf(SL_FAILURE, "425-Unable to bind data socket.\r\n425 %s.", 172 strerror(errno)); 173 return 1; 174 } 175 if (!strcasecmp(config_getoption("DATAPORT20"), "yes")) 176 seteuid(curuid); 177 sa.sin_family = AF_INET; 178 if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) == -1) { 179 control_printf(SL_FAILURE, "425-Unable to establish data connection.\r\n" 180 "425 %s.", strerror(errno)); 181 return 1; 182 } 183 } 184 control_printf(SL_SUCCESS, "150 %s data connection established.", 185 xfertype == TYPE_BINARY ? "BINARY" : "ASCII"); 186 return 0; 187} 188 189void init_userinfo() 190{ 191#ifndef NO_GETPWNAM 192 struct passwd *temp = getpwnam(user); 193 if (temp) { 194 userinfo.pw_name = strdup(temp->pw_name); 195 userinfo.pw_passwd = strdup(temp->pw_passwd); 196 userinfo.pw_uid = temp->pw_uid; 197 userinfo.pw_gid = temp->pw_gid; 198 userinfo.pw_gecos = strdup(temp->pw_gecos); 199 userinfo.pw_dir = strdup(temp->pw_dir); 200 userinfo.pw_shell = strdup(temp->pw_shell); 201 userinfo_set = 1; 202 } 203#endif 204} 205 206/** 207 * foxconn,start by cliff wang @ checking remote access for log 208 * */ 209#if 0 210int isLanSubnet(char *ipAddr, char *lan_addr, char *lan_mask) 211{ 212 long netAddr, netMask, netIp; 213 214 netAddr = inet_addr(lan_addr); 215 netMask = inet_addr(lan_mask); 216 netIp = inet_addr(ipAddr); 217 218 if ((netAddr & netMask) != (netIp & netMask)) 219 return FALSE; 220 return TRUE; 221} 222 223static int check_ip_info_by_name(char *intf) 224{ 225 int fd; 226 struct ifreq ifr; 227 struct ifreq mask; 228 229 fd = socket(AF_INET, SOCK_DGRAM, 0); 230 231 /* I want to get an IPv4 IP address */ 232 ifr.ifr_addr.sa_family = AF_INET; 233 234 /* I want IP address attached to "eth0" */ 235 strncpy(ifr.ifr_name, intf, IFNAMSIZ-1); 236 strncpy(mask.ifr_name, intf, IFNAMSIZ-1); 237 238 ioctl(fd, SIOCGIFADDR, &ifr); 239 ioctl(fd, SIOCGIFNETMASK, &mask); 240 241 close(fd); 242 243 /* display result */ 244 printf("ip: %s\n", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); 245 printf("mask: %s\n", inet_ntoa(((struct sockaddr_in *)&mask.ifr_netmask)->sin_addr)); 246 247 return isLanSubnet(remotehostname, 248 inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr), 249 inet_ntoa(((struct sockaddr_in *)&mask.ifr_netmask)->sin_addr) ); 250} 251 252int ambitWriteLog(char *pcLog, int iLen) 253{ 254 FILE *fp; 255 256 if (!(fp = fopen("/dev/aglog", "r+"))) 257 { 258 printf("%s:open /dev/aglog fail\n", __FUNCTION__); 259 return -1; 260 } 261 262 *(pcLog + iLen) = '\0'; 263 fwrite(pcLog, sizeof(char), iLen+1, fp); 264 fclose(fp); 265 return 0; 266} 267 268#include <sys/un.h> 269#include <stddef.h> 270 271void fifo_write(char *buf) 272{ 273 char fn[]="/tmp/local_sock"; 274 int wfd; 275 struct sockaddr_un name; 276 int sock; 277 size_t size; 278 279 sock = socket (PF_LOCAL, SOCK_DGRAM, 0); 280 281 name.sun_family = AF_LOCAL; 282 strncpy (name.sun_path, "/tmp/local_sock", sizeof (name.sun_path)); 283 name.sun_path[sizeof (name.sun_path) - 1] = '\0'; 284 285 size = (offsetof (struct sockaddr_un, sun_path) + strlen (name.sun_path) + 1); 286 287 connect(sock, (struct sockaddr *) &name, size); 288 289 write(sock, buf, strlen(buf)); 290 291 fflush(sock); 292 293 close(sock); 294} 295#endif 296 297/* 298 * foxconn,end by cliff wang @ checking remote access for log 299 * **/ 300 301void command_user(char *username) 302{ 303 char *alias; 304 305 /* Foxconn addedd start pling 06/10/2009*/ 306 /* If all shared folders are 'All - no password', 307 * then no need to login for "FTP". 308 * Also, take care of duplicate login. 309 */ 310 extern int all_no_password; 311 312 char modified_user[] = "guest"; 313 314 //if ( strlen(username) != 0 && strcmp(username, "admin") != 0 ) { 315 if (all_no_password) { 316 if (strcmp(user, "guest") ) { 317 /* first time */ 318 username = modified_user; 319 } else { 320 /* duplicate login */ 321 control_printf (SL_SUCCESS, "230 User logged in."); 322 write_usb_access_log(); 323 return; 324 } 325 } 326 /* foxconn, cliff wang, remove for 2nd login browser using anonymous user first */ 327 /* Foxconn, cliffwang, router spec 2.0, any account can access 328 * * non-amdin folder 329 * * */ 330 else if ( strlen(username) != 0 && strcmp(username, "anonymous") == 0 ) { 331 control_printf (SL_SUCCESS, "331 input email as password."); 332 state = STATE_USER; 333 return; 334 } 335 336 /* Foxconn added end pling 06/10/2009*/ 337#if 0 338 if (state) { 339 // control_printf(SL_FAILURE, "503 Username already given."); 340 state = STATE_AUTHENTICATED; 341 return; 342 } 343#endif 344 mystrncpy(user, username, sizeof(user) - 1); 345 userinfo_set = 1; /* Dirty! */ 346 alias = (char *) config_getoption("ALIAS"); 347 userinfo_set = 0; 348 if (alias[0] != '\0') 349 mystrncpy(user, alias, sizeof(user) - 1); 350 init_userinfo(); 351#ifdef DEBUG 352 bftpd_log("Trying to log in as %s.\n", user); 353#endif 354 expand_groups(); 355 if (!strcasecmp(config_getoption("ANONYMOUS_USER"), "yes")) 356 bftpd_login(""); 357 else { 358 state = STATE_USER; 359 control_printf(SL_SUCCESS, "331 Password please."); 360 } 361} 362 363void command_pass(char *password) 364{ 365 /* 366 * Foxconn, added by cliff wang @ for logging usb access for ftp 367 * */ 368 char tmpStr[64]; 369 //int bIsLanIP = check_ip_info_by_name("br0"); 370 //int bIsLanIP = 1; 371 //fifo_write("start to auth\n"); 372 373 if ( strlen(user) != 0 && strcmp(user, "anonymous") == 0 ) { 374 // STATE_CONNECTED, STATE_USER, STATE_AUTHENTICATED 375 state = STATE_CONNECTED; 376 control_printf (SL_SUCCESS, "530 Sorry anonymous now allowed."); 377 exit(0); 378 } 379 380 if (state > STATE_USER) { 381 control_printf(SL_FAILURE, "503 Already logged in."); 382 return; 383 } 384 385 if (bftpd_login(password)) { 386#if 0 387 if ( !bIsLanIP ) { 388 sprintf(tmpStr, " [USB remote access rejected] from source %s through FTP, ", remotehostname); 389 //ambitWriteLog(tmpStr, strlen(tmpStr)); 390 fifo_write(tmpStr); 391 } 392#endif 393 write_usb_fail_log(); 394 395 bftpd_log("Login as user '%s' failed.\n", user); 396 control_printf(SL_FAILURE, "421 Login incorrect."); 397 exit(0); 398 } else { 399#if 0 400 if ( !bIsLanIP ) { 401 sprintf(tmpStr, " [USB remote access] from source %s through FTP, ", remotehostname); 402 //ambitWriteLog(tmpStr, strlen(tmpStr)); 403 fifo_write(tmpStr); 404 } 405#endif 406 } 407} 408 409void command_pwd(char *params) 410{ 411 char *my_cwd = NULL; 412 413 my_cwd = bftpd_cwd_getcwd(); 414 if (my_cwd) 415 { 416 control_printf(SL_SUCCESS, "257 \"%s\" is the current working directory.", my_cwd); 417 free(my_cwd); 418 } 419} 420 421 422void command_type(char *params) 423{ 424 if ((*params == 'A') || (*params == 'a')) { 425 control_printf(SL_SUCCESS, "200 Transfer type changed to ASCII"); 426 xfertype = TYPE_ASCII; 427 } else if ((*params == 'I') || (*params == 'i')) { 428 control_printf(SL_SUCCESS, "200 Transfer type changed to BINARY"); 429 xfertype = TYPE_BINARY; 430 } else 431 control_printf(SL_FAILURE, "500 Type '%c' not supported.", *params); 432} 433 434void command_port(char *params) { 435 unsigned long a0, a1, a2, a3, p0, p1, addr; 436 if (epsvall) { 437 control_printf(SL_FAILURE, "500 EPSV ALL has been called."); 438 return; 439 } 440 sscanf(params, "%lu,%lu,%lu,%lu,%lu,%lu", &a0, &a1, &a2, &a3, &p0, &p1); 441 addr = htonl((a0 << 24) + (a1 << 16) + (a2 << 8) + a3); 442 if((addr != remotename.sin_addr.s_addr) &&( strncasecmp(config_getoption("ALLOW_FXP"), "yes", 3))) { 443 control_printf(SL_FAILURE, "500 The given address is not yours."); 444 return; 445 } 446 sa.sin_addr.s_addr = addr; 447 sa.sin_port = htons((p0 << 8) + p1); 448 if (pasv) { 449 close(sock); 450 pasv = 0; 451 } 452 control_printf(SL_SUCCESS, "200 PORT %lu.%lu.%lu.%lu:%lu OK", 453 a0, a1, a2, a3, (p0 << 8) + p1); 454} 455 456void command_eprt(char *params) { 457 char delim; 458 int af; 459 char addr[51]; 460 char foo[20]; 461 int port; 462 if (epsvall) { 463 control_printf(SL_FAILURE, "500 EPSV ALL has been called."); 464 return; 465 } 466 if (strlen(params) < 5) { 467 control_printf(SL_FAILURE, "500 Syntax error."); 468 return; 469 } 470 delim = params[0]; 471 sprintf(foo, "%c%%i%c%%50[^%c]%c%%i%c", delim, delim, delim, delim, delim); 472 if (sscanf(params, foo, &af, addr, &port) < 3) { 473 control_printf(SL_FAILURE, "500 Syntax error."); 474 return; 475 } 476 if (af != 1) { 477 control_printf(SL_FAILURE, "522 Protocol unsupported, use (1)"); 478 return; 479 } 480 sa.sin_addr.s_addr = inet_addr(addr); 481 if ((sa.sin_addr.s_addr != remotename.sin_addr.s_addr) && (strncasecmp(config_getoption("ALLOW_FXP"), "yes", 3))) { 482 control_printf(SL_FAILURE, "500 The given address is not yours."); 483 return; 484 } 485 sa.sin_port = htons(port); 486 if (pasv) { 487 close(sock); 488 pasv = 0; 489 } 490 control_printf(SL_FAILURE, "200 EPRT %s:%i OK", addr, port); 491} 492 493void command_pasv(char *foo) 494{ 495 int a1, a2, a3, a4; 496 socklen_t namelen; 497 struct sockaddr_in localsock; 498 char *my_override_ip; 499 500 if (epsvall) { 501 control_printf(SL_FAILURE, "500 EPSV ALL has been called."); 502 return; 503 } 504 pasvsock = socket(AF_INET, SOCK_STREAM, 0); 505 sa.sin_addr.s_addr = INADDR_ANY; 506 sa.sin_family = AF_INET; 507 508 if (!config_getoption("PASSIVE_PORTS") || !strlen(config_getoption("PASSIVE_PORTS"))) { 509 /* bind to any port */ 510 sa.sin_port = 0; 511 if (bind(pasvsock, (struct sockaddr *) &sa, sizeof(sa)) == -1) 512 { 513 control_printf(SL_FAILURE, "425-Error: Unable to bind data socket.\r\n425 %s", strerror(errno)); 514 return; 515 } 516 } 517 518 else { 519 int i = 0, success = 0, port; 520 for (;;) { 521 port = int_from_list(config_getoption("PASSIVE_PORTS"), i++); 522 if (port < 0) 523 break; 524 sa.sin_port = htons(port); 525 if (bind(pasvsock, (struct sockaddr *) &sa, sizeof(sa)) == 0) { 526 success = 1; 527#ifdef DEBUG 528 bftpd_log("Passive mode: Successfully bound port %d\n", port); 529#endif 530 break; 531 } 532 } /* end of for loop */ 533 if (!success) { 534 control_printf(SL_FAILURE, "425 Error: Unable to bind data socket."); 535 return; 536 } 537 prepare_sock(pasvsock); 538 } /* end of else using list of ports */ 539 540 if (listen(pasvsock, 1)) { 541 control_printf(SL_FAILURE, "425-Error: Unable to make socket listen.\r\n425 %s", 542 strerror(errno)); 543 return; 544 } 545 namelen = sizeof(localsock); 546 getsockname(pasvsock, (struct sockaddr *) &localsock, (socklen_t *) &namelen); 547 548 /* see if we should over-ride the IP address sent to the client */ 549 my_override_ip = config_getoption("OVERRIDE_IP"); 550 if (my_override_ip[0]) 551 { 552 sscanf( my_override_ip, "%i.%i.%i.%i", 553 &a1, &a2, &a3, &a4); 554 } 555 else /* noraml, no over-ride */ 556 { 557 sscanf((char *) inet_ntoa(name.sin_addr), "%i.%i.%i.%i", 558 &a1, &a2, &a3, &a4); 559 } 560 561 control_printf(SL_SUCCESS, "227 Entering Passive Mode (%i,%i,%i,%i,%i,%i)", a1, a2, a3, a4, 562 ntohs(localsock.sin_port) >> 8, ntohs(localsock.sin_port) & 0xFF); 563 pasv = 1; 564} 565 566void command_epsv(char *params) 567{ 568 struct sockaddr_in localsock; 569 socklen_t namelen; 570 int af; 571 if (params[0]) { 572 if (!strncasecmp(params, "ALL", 3)) 573 epsvall = 1; 574 else { 575 if (sscanf(params, "%i", &af) < 1) { 576 control_printf(SL_FAILURE, "500 Syntax error."); 577 return; 578 } else { 579 if (af != 1) { 580 control_printf(SL_FAILURE, "522 Protocol unsupported, use (1)"); 581 return; 582 } 583 } 584 } 585 } 586 pasvsock = socket(AF_INET, SOCK_STREAM, 0); 587 sa.sin_addr.s_addr = INADDR_ANY; 588 sa.sin_port = 0; 589 sa.sin_family = AF_INET; 590 if (bind(pasvsock, (struct sockaddr *) &sa, sizeof(sa)) == -1) { 591 control_printf(SL_FAILURE, "500-Error: Unable to bind data socket.\r\n425 %s", 592 strerror(errno)); 593 return; 594 } 595 if (listen(pasvsock, 1)) { 596 control_printf(SL_FAILURE, "500-Error: Unable to make socket listen.\r\n425 %s", 597 strerror(errno)); 598 return; 599 } 600 namelen = sizeof(localsock); 601 getsockname(pasvsock, (struct sockaddr *) &localsock, (socklen_t *) &namelen); 602 control_printf(SL_SUCCESS, "229 Entering extended passive mode (|||%i|)", 603 ntohs(localsock.sin_port)); 604 pasv = 1; 605} 606 607char test_abort(char selectbefore, int file, int sock) 608{ 609 char str[256]; 610 fd_set rfds; 611 struct timeval tv; 612 if (selectbefore) { 613 tv.tv_sec = 0; 614 tv.tv_usec = 0; 615 FD_ZERO(&rfds); 616 FD_SET(fileno(stdin), &rfds); 617 if (!select(fileno(stdin) + 1, &rfds, NULL, NULL, &tv)) 618 return 0; 619 } 620 fgets(str, sizeof(str), stdin); 621 if (strstr(str, "ABOR")) { 622 control_printf(SL_SUCCESS, "426 Transfer aborted."); 623 close(file); 624 close(sock); 625 control_printf(SL_SUCCESS, "226 Aborted."); 626 bftpd_log("Client aborted file transmission.\n"); 627 alarm(control_timeout); 628 return 1; 629 } 630 return 0; 631} 632 633void command_allo(char *foo) 634{ 635 command_noop(foo); 636} 637 638 639/* This function allows the storage of multiple files on the server. */ 640void command_mput(char *filenames) 641{ 642 char filename[MAXCMD]; /* single filename */ 643 int from_index, to_index; /* position in "filenames" and "filename" */ 644 645 from_index = 0; /* start at begining of filenames */ 646 memset(filename, 0, MAXCMD); /* clear filename */ 647 to_index = 0; 648 649 /* go until we find a NULL character */ 650 while ( filenames[from_index] > 0) 651 { 652 /* copy filename until we hit a space */ 653 if (filenames[from_index] == ' ') 654 { 655 /* got a full filename */ 656 command_stor(filename); 657 /* clear filename and reset to_index */ 658 to_index = 0; 659 memset(filename, 0, MAXCMD); 660 661 while (filenames[from_index] == ' ') 662 from_index++; /* goto next position */ 663 } 664 665 /* if we haven't hit a space, then copy the letter */ 666 else 667 { 668 filename[to_index] = filenames[from_index]; 669 to_index++; 670 from_index++; 671 /* if the next character is a NULL, then this is the end of the filename */ 672 if (! filenames[from_index]) 673 { 674 command_stor(filename); /* get the file */ 675 to_index = 0; /* reset filename index */ 676 memset(filename, 0, MAXCMD); /* clear filename buffer */ 677 from_index++; /* goto next character */ 678 } 679 } 680 681 /* if the buffer is getting too big, then stop */ 682 if (to_index > (MAXCMD - 2) ) 683 { 684 bftpd_log("Error: Filename in '%s' too long.\n", filenames); 685 return; 686 } 687 688 } /* end of while */ 689 690} 691 692 693#define MAX_BUFFER_SIZE (4*65536) // Foxconn added pling 06/19/2009 /* wklin modified */ 694void do_stor(char *filename, int flags) 695{ 696 char *buffer; 697 int fd, i, max; 698 fd_set rfds; 699 struct timeval tv; 700 char *p, *pp; 701 char *mapped = bftpd_cwd_mappath(filename); 702 703 int my_buffer_size; /* total transfer buffer size divided by number of clients */ 704 int num_clients; /* number of clients connected to the server */ 705 int new_num_clients; 706 int xfer_delay; 707 int attempt_gzip = FALSE; 708#ifdef HAVE_ZLIB_H 709 gzFile my_zip_file = NULL; 710#endif 711 712 713 /* Foxconn, added by MJ., 2010.04.08, for check if file is locked. */ 714#ifdef LOCK_DEBUG 715 printf("%s begins.\n", __FUNCTION__); 716#endif 717 /*FIXME: We have to check file lock before pre_write_script */ 718 719 fd = open(mapped, O_RDONLY); 720 if (fd >= 0) /* file exists */ 721 { 722 struct flock lock; 723 lock.l_type = F_WRLCK; 724 lock.l_whence = SEEK_SET; 725 lock.l_start = 0; 726 lock.l_len = 0; 727 if (!fcntl(fd, F_GETLK, &lock)) 728 { 729#ifdef LOCK_DEBUG 730 printf("1.%s: l_type:%d\n", __FUNCTION__, lock.l_type); 731#endif 732 if (lock.l_type != F_UNLCK) // File is locked by other process 733 { 734 bftpd_log("Error: '%s' while trying to store file '%s'.\n", 735 strerror(errno), filename); 736 control_printf(SL_FAILURE, "550 Error: File is read-only"); 737 close(fd); /* make sure it is not open */ 738 free(mapped); 739 return; 740 } 741 } 742 close(fd); 743 } 744 /* Foxconn, ended by MJ., 2010.04.09 */ 745 746 747 if (pre_write_script) 748 run_script(pre_write_script, mapped); 749 750#ifdef HAVE_ZLIB_H 751 if (! strcmp( config_getoption("GZ_UPLOAD"), "yes") ) 752 { 753 attempt_gzip = TRUE; 754 strcat(mapped, ".gz"); 755 } 756 else 757 attempt_gzip = FALSE; 758#endif 759 760 /* See if we should delay between data transfers */ 761 xfer_delay = strtoul( config_getoption("XFER_DELAY"), NULL, 0); 762 763 /* Check to see if the file exists and if we can over-write 764 it, if it does. -- Jesse */ 765 766 fd = open(mapped, O_RDONLY); 767 if (fd >= 0) /* file exists */ 768 { 769 /* FIXME: Foxconn, commented by MJ., 2010.04.09, We have to do this before pre_write_script. */ 770#if 0 771 /* Foxconn added start pling 06/25/2009 */ 772 /* Try to lock this file for write access. 773 * If failed, don't allow write. 774 */ 775 struct flock lock; 776 lock.l_type = F_WRLCK; 777 lock.l_whence = SEEK_SET; 778 lock.l_start = 0; 779 lock.l_len = 0; 780 781 if (!fcntl(fd, F_GETLK, &lock)) 782 { 783 printf("2.%s: l_type:%d\n", __FUNCTION__, lock.l_type); 784 if (lock.l_type != F_UNLCK) // File is locked by other process 785 { 786 bftpd_log("Error: '%s' while trying to store file '%s'.\n", 787 strerror(errno), filename); 788 control_printf(SL_FAILURE, "550 Error: File is read-only"); 789 close(fd); /* make sure it is not open */ 790 free(mapped); 791 return; 792 } 793 } 794 /* Foxconn added end pling 06/25/2009 */ 795#endif 796 /* close the file */ 797 close(fd); 798 799 /* check if we can over-write it */ 800 if ( !strcasecmp( config_getoption("ALLOWCOMMAND_DELE"), "no") ) 801 { 802 bftpd_log("Not allowed to over-write '%s'.\n", filename); 803 control_printf(SL_FAILURE, 804 "553 Error: Remote file is write protected."); 805 806 free(mapped); 807 close(sock); 808 return; 809 } 810 } 811 812 if (! attempt_gzip) 813 { 814 fd = open(mapped, flags, 00666); 815 /* 816 do this below 817 if (mapped) 818 free(mapped); 819 */ 820 if (fd == -1) { 821 bftpd_log("Error: '%s' while trying to store file '%s'.\n", 822 strerror(errno), filename); 823 control_printf(SL_FAILURE, "553 Error: %s.", strerror(errno)); 824 825 close(fd); /* make sure it is not open */ 826 if (post_write_script) 827 run_script(post_write_script, mapped); 828 free(mapped); 829 return; 830 } 831 832 /* Foxconn added start pling 06/25/2009 */ 833 /* Lock this file for write access */ 834 struct flock lock; 835 lock.l_type = F_WRLCK; 836 lock.l_whence = SEEK_SET; 837 lock.l_start = 0; 838 lock.l_len = 0; 839 if (fcntl(fd, F_SETLK, &lock)) 840 { 841 bftpd_log("Error: '%s' while trying to store file '%s'.\n", 842 strerror(errno), filename); 843 control_printf(SL_FAILURE, "550 Error: File is read-only"); 844 close(fd); /* make sure it is not open */ 845 free(mapped); 846 return; 847 } 848 /* Foxconn added end pling 06/25/2009 */ 849 } 850 851#ifdef HAVE_ZLIB_H 852 if ( attempt_gzip ) 853 { 854 my_zip_file = gzopen(mapped, "wb+"); 855 if (mapped) 856 free(mapped); 857 if (! my_zip_file) 858 { 859 control_printf(SL_FAILURE, "553 Error: An error occured creating compressed file."); 860 close(sock); 861 close(fd); 862 return; 863 } 864 } 865#endif 866 867 bftpd_log("Client is storing file '%s'.\n", filename); 868 if (dataconn()) 869 { 870 close(fd); 871 if (post_write_script) 872 run_script(post_write_script, mapped); 873 free(mapped); 874 return; 875 } 876 877 /* Figure out how big the transfer buffer should be. 878 This will be the total size divided by the number of clients connected. 879 -- Jesse 880 */ 881 num_clients = bftpdutmp_usercount("*"); 882 /* Foxconn modified start pling 06/19/2009 */ 883 /* For better throughput performance */ 884 // my_buffer_size = get_buffer_size(num_clients); 885 my_buffer_size = MAX_BUFFER_SIZE; 886 /* Foxconn modified end pling 06/19/2009 */ 887 888 alarm(0); 889 /* Foxconn modified start pling 06/19/2009 */ 890 /* For better throughput performance */ 891 // buffer = malloc(xfer_bufsize); 892 buffer = malloc(MAX_BUFFER_SIZE); 893 /* Foxconn modified end pling 06/19/2009 */ 894 /* Check to see if we are out of memory. -- Jesse */ 895 if (! buffer) 896 { 897 bftpd_log("Unable to create buffer to receive file.\n", 0); 898 control_printf(SL_FAILURE, "553 Error: An unknown error occured on the server."); 899 if (fd >= 0) 900 close(fd); 901 close(sock); 902 return; 903 } 904 905 lseek(fd, offset, SEEK_SET); 906 offset = 0; 907 /* Do not use the whole buffer, because a null byte has to be 908 * written after the string in ASCII mode. */ 909 max = (sock > fileno(stdin) ? sock : fileno(stdin)) + 1; 910 for (;;) { 911 FD_ZERO(&rfds); 912 FD_SET(sock, &rfds); 913 FD_SET(fileno(stdin), &rfds); 914 915 tv.tv_sec = data_timeout; 916 tv.tv_usec = 0; 917 if (!select(max, &rfds, NULL, NULL, &tv)) { 918 close(sock); 919 close(fd); 920 control_printf(SL_FAILURE, "426 Kicked due to data transmission timeout."); 921 bftpd_log("Kicked due to data transmission timeout.\n"); 922 /* Before we exit, let's remove our entry in the log file. -- Jesse */ 923 if (post_write_script) 924 run_script(post_write_script, mapped); 925 926 bftpdutmp_end(); 927 exit(0); 928 } 929 if (FD_ISSET(fileno(stdin), &rfds)) { 930 test_abort(0, fd, sock); 931 if (buffer) 932 free(buffer); 933 close(fd); 934 if (post_write_script) 935 run_script(post_write_script, mapped); 936 free(mapped); 937 return; 938 } 939 940 if (!((i = recv(sock, buffer, my_buffer_size - 1, 0)))) 941 break; 942 bytes_recvd += i; 943 if (xfertype == TYPE_ASCII) { 944 buffer[i] = '\0'; 945 /* on ASCII stransfer, strip character 13 */ 946 p = pp = buffer; 947 while (*p) { 948 if ((unsigned char) *p == 13) 949 p++; 950 else 951 *pp++ = *p++; 952 } 953 *pp++ = 0; 954 i = strlen(buffer); 955 } // end of if ASCII type transfer 956 957#ifdef HAVE_ZLIB_H 958 if (my_zip_file) 959 gzwrite( my_zip_file, buffer, i ); 960#endif 961 if(! attempt_gzip) 962 { 963 /* Foxconn modify start, Max Ding, 06/09/2011 @IR-083 of WNR3500Lv2 */ 964 /* IR-083: FTP write issue when drive is full 965 * When USB disk is full, write will fail, 966 * Solution: Then should return error, and close socket and fd. 967 * Refer to FileZilla behavior: return "550 can't access file" 968 */ 969 if (i != write(fd, buffer, i)) 970 { 971 close(sock); 972 close(fd); 973 control_printf(SL_FAILURE, "550 can't access file."); 974 bftpd_log("can't access file.\n"); 975 if (post_write_script) 976 run_script(post_write_script, mapped); 977 978 bftpdutmp_end(); 979 if (buffer) 980 free(buffer); 981 if (mapped) 982 free(mapped); 983 return; 984 } 985 /* Foxconn modify end, Max Ding, 06/09/2011 */ 986 } 987 988 /* Check to see if our bandwidth usage should change. -- Jesse */ 989 new_num_clients = bftpdutmp_usercount("*"); 990 if (new_num_clients != num_clients) 991 { 992 num_clients = new_num_clients; 993 my_buffer_size = get_buffer_size(num_clients); 994 } 995 996 /* check for transfer delay */ 997 if ( xfer_delay ) 998 { 999 struct timeval wait_time; 1000 1001 wait_time.tv_sec = 0; 1002 wait_time.tv_usec = xfer_delay; 1003 select( 0, NULL, NULL, NULL, &wait_time); 1004 } 1005 1006 1007 } // end of for loop, reading 1008 1009 free(buffer); 1010#ifdef HAVE_ZLIB_H 1011 gzclose(my_zip_file); 1012#else 1013 close(fd); 1014#endif 1015 1016 close(sock); 1017 alarm(control_timeout); 1018 offset = 0; 1019 control_printf(SL_SUCCESS, "226 File transmission successful."); 1020 bftpd_log("File transmission successful.\n"); 1021 if (post_write_script) 1022 run_script(post_write_script, mapped); 1023 1024 free(mapped); 1025} 1026 1027void command_stor(char *filename) 1028{ 1029 do_stor(filename, O_CREAT | O_WRONLY | O_TRUNC); 1030} 1031 1032void command_appe(char *filename) 1033{ 1034 do_stor(filename, O_CREAT | O_WRONLY | O_APPEND); 1035} 1036 1037 1038 1039 1040/* Send multpile files to the client. */ 1041void command_mget(char *filenames) 1042{ 1043 char filename[MAXCMD]; /* single filename */ 1044 int from_index, to_index; /* position in "filenames" and "filename" */ 1045 1046 from_index = 0; /* start at begining of filenames */ 1047 memset(filename, 0, MAXCMD); /* clear filename */ 1048 to_index = 0; 1049 1050 /* go until we find a NULL character */ 1051 while ( filenames[from_index] > 0) 1052 { 1053 /* copy filename until we hit a space */ 1054 if (filenames[from_index] == ' ') 1055 { 1056 /* got a full filename */ 1057 command_retr(filename); 1058 /* clear filename and reset to_index */ 1059 to_index = 0; 1060 memset(filename, 0, MAXCMD); 1061 1062 while (filenames[from_index] == ' ') 1063 from_index++; /* goto next position */ 1064 } 1065 1066 /* if we haven't hit a space, then copy the letter */ 1067 else 1068 { 1069 filename[to_index] = filenames[from_index]; 1070 to_index++; 1071 from_index++; 1072 /* if the next character is a NULL, then this is the end of the filename */ 1073 if (! filenames[from_index]) 1074 { 1075 command_retr(filename); /* send the file */ 1076 to_index = 0; /* reset filename index */ 1077 memset(filename, 0, MAXCMD); /* clear filename buffer */ 1078 from_index++; /* goto next character */ 1079 } 1080 } 1081 1082 /* if the buffer is getting too big, then stop */ 1083 if (to_index > (MAXCMD - 2) ) 1084 { 1085 bftpd_log("Error: Filename in '%s' too long.\n", filenames); 1086 return; 1087 } 1088 1089 } /* end of while */ 1090 1091} 1092 1093void command_retr(char *filename) 1094{ 1095 int num_clients, new_num_clients; /* number of connectiosn to the server */ 1096 int my_buffer_size; /* size of the transfer buffer to use */ 1097 char *mapped; 1098 char *buffer; 1099 int xfer_delay; 1100 struct timeval wait_time; 1101 ssize_t send_status; 1102#if (defined(WANT_GZIP) || defined(HAVE_ZLIB_H)) 1103 gzFile gzfile; 1104#endif 1105 int phile; 1106 int i, whattodo = DO_NORMAL; 1107 struct stat statbuf; 1108#if (defined(WANT_TAR) && defined(WANT_GZIP)) 1109 int filedes[2]; 1110#endif 1111#if (defined(WANT_TAR) || defined(WANT_GZIP)) 1112 char *foo; 1113#endif 1114#ifdef WANT_TAR 1115 char *argv[4]; 1116#endif 1117 1118 xfer_delay = strtoul( config_getoption("XFER_DELAY"), NULL, 0); 1119 1120 mapped = bftpd_cwd_mappath(filename); 1121 if (! mapped) 1122 { 1123 bftpd_log("Memory error in sending file.\n", 0); 1124 control_printf(SL_FAILURE, "553 An unknown error occured on the server.", 9); 1125 return; 1126 } 1127 1128 /* Foxconn added start pling 06/07/2010 */ 1129 /* BTS-A20102624: Chrome FTP fix: 1130 * handle the case where FTP client tries to access /shares/shares 1131 */ 1132 if (strncmp(filename,"/shares/shares", strlen("/shares/shares")) == 0) 1133 { 1134 if (stat(mapped, &statbuf)) 1135 { 1136 free(mapped); 1137 filename += strlen("/shares"); 1138 mapped = bftpd_cwd_mappath(filename); 1139 } 1140 } 1141 /* Foxconn added end pling 06/07/2010 */ 1142 1143 phile = open(mapped, O_RDONLY); 1144 if (phile == -1) { // failed to open a file 1145#if (defined(WANT_TAR) && defined(WANT_GZIP)) 1146 if ((foo = strstr(filename, ".tar.gz"))) 1147 if (strlen(foo) == 7) { 1148 whattodo = DO_TARGZ; 1149 *foo = '\0'; 1150 } 1151#endif 1152#ifdef WANT_TAR 1153 if ((foo = strstr(filename, ".tar"))) 1154 if (strlen(foo) == 4) { 1155 whattodo = DO_TARONLY; 1156 *foo = '\0'; 1157 } 1158#endif 1159#ifdef WANT_GZIP 1160 if ((foo = strstr(filename, ".gz"))) 1161 if (strlen(foo) == 3) { 1162 whattodo = DO_GZONLY; 1163 *foo = '\0'; 1164 } 1165#endif 1166 if (whattodo == DO_NORMAL) { 1167 bftpd_log("Error: '%s' while trying to receive file '%s'.\n", 1168 strerror(errno), filename); 1169 control_printf(SL_FAILURE, "553 Error: %s.", strerror(errno)); 1170 if (mapped) 1171 free(mapped); 1172 return; 1173 } 1174 } 1175 1176#ifdef HAVE_ZLIB_H 1177 else // we did open a file 1178 { 1179 char *my_temp; 1180 char *zip_option; 1181 1182 my_temp = strstr(filename, ".gz"); 1183 zip_option = config_getoption("GZ_DOWNLOAD"); 1184 if (my_temp) 1185 { 1186 if ( ( strlen(my_temp) == 3) && (! strcasecmp(zip_option, "yes") ) ) 1187 whattodo = DO_GZUNZIP; 1188 } 1189 } 1190#endif 1191 1192 /* Foxconn added start pling 06/25/2009 */ 1193 /* Place a read Lock on this file to prevent it 1194 * from any other write access 1195 */ 1196 struct flock lock; 1197 lock.l_type = F_RDLCK; 1198 lock.l_whence = SEEK_SET; 1199 lock.l_start = 0; 1200 lock.l_len = 0; 1201 1202 fcntl(phile, F_GETLK, &lock); 1203 1204 /* Foxconn added by MJ., for file lock checking*/ 1205#ifdef LOCK_DEBUG 1206 printf("1.%s: l_type:%d\n", __FUNCTION__, lock.l_type); 1207#endif 1208 if(lock.l_type == F_UNLCK) 1209 { 1210 lock.l_type = F_RDLCK; 1211 fcntl(phile, F_SETLK, &lock); 1212 } 1213 else if(lock.l_type == F_WRLCK) 1214 {//FIXME: [MJ.] Should we do this? block reading while other is writing? 1215 close(phile); 1216 if(mapped) free(mapped); 1217 1218 return; 1219 } 1220 /* Foxconn ended by MJ., for file lock checking*/ 1221 1222 /* Foxconn added end pling 06/25/2009 */ 1223 1224 stat(mapped, (struct stat *) &statbuf); 1225 if (S_ISDIR(statbuf.st_mode)) { 1226 control_printf(SL_FAILURE, "550 Error: Is a directory."); 1227 if (mapped) 1228 free(mapped); 1229 return; 1230 } 1231#ifndef QUICK_FIX_ISSUES 1232 //FIXME 1233 if ((((statbuf.st_size - offset) * ratio_send) / ratio_recv > bytes_recvd 1234 - bytes_sent) && (strcmp((char *) config_getoption("RATIO"), "none"))) { 1235 bftpd_log("Error: 'File too big (ratio)' while trying to receive file " 1236 "'%s'.\n", filename); 1237 control_printf(SL_FAILURE, "553 File too big. Send at least %i bytes first.", 1238 (int) (((statbuf.st_size - offset) * ratio_send) / ratio_recv) 1239 - bytes_recvd); 1240 if (mapped) 1241 free(mapped); 1242 return; 1243 } 1244#endif 1245 bftpd_log("Client is receiving file '%s'.\n", filename); 1246 switch (whattodo) { 1247#if (defined(WANT_TAR) && defined(WANT_GZIP)) 1248 case DO_TARGZ: 1249 close(phile); 1250 if (dataconn()) { 1251 if (mapped) 1252 free(mapped); 1253 return; 1254 } 1255 alarm(0); 1256 pipe(filedes); 1257 if (fork()) { 1258 buffer = malloc(xfer_bufsize); 1259 /* check to make sure alloc worked */ 1260 if (! buffer) 1261 { 1262 if (mapped) 1263 free(mapped); 1264 bftpd_log("Memory error in sending file.\n", 0); 1265 control_printf(SL_FAILURE, "553 An unknown error occured on the server.", 9); 1266 return; 1267 } 1268 1269 /* find the size of the transfer buffer divided by number of connections */ 1270 num_clients = bftpdutmp_usercount("*"); 1271 my_buffer_size = get_buffer_size(num_clients); 1272 1273 close(filedes[1]); 1274 gzfile = gzdopen(sock, "wb"); 1275 while ((i = read(filedes[0], buffer, my_buffer_size))) { 1276 gzwrite(gzfile, buffer, i); 1277 test_abort(1, phile, sock); 1278 1279 /* check for a change in number of connections */ 1280 new_num_clients = bftpdutmp_usercount("*"); 1281 if (new_num_clients != num_clients) 1282 { 1283 num_clients = new_num_clients; 1284 my_buffer_size = get_buffer_size(num_clients); 1285 } 1286 /* pause between transfers */ 1287 if (xfer_delay) 1288 { 1289 wait_time.tv_sec = 0; 1290 wait_time.tv_usec = xfer_delay; 1291 select( 0, NULL, NULL, NULL, &wait_time); 1292 } 1293 } // end of while 1294 free(buffer); 1295 gzclose(gzfile); 1296 wait(NULL); /* Kill the zombie */ 1297 } else { 1298 stderr = devnull; 1299 close(filedes[0]); 1300 close(fileno(stdout)); 1301 dup2(filedes[1], fileno(stdout)); 1302 setvbuf(stdout, NULL, _IONBF, 0); 1303 argv[0] = "tar"; 1304 argv[1] = "cf"; 1305 argv[2] = "-"; 1306 argv[3] = mapped; 1307 exit(pax_main(4, argv)); 1308 } 1309 break; 1310#endif 1311#ifdef WANT_TAR 1312 case DO_TARONLY: 1313 if (dataconn()) { 1314 if (mapped) 1315 free(mapped); 1316 return; 1317 } 1318 alarm(0); 1319 if (fork()) 1320 wait(NULL); 1321 else { 1322 stderr = devnull; 1323 dup2(sock, fileno(stdout)); 1324 argv[0] = "tar"; 1325 argv[1] = "cf"; 1326 argv[2] = "-"; 1327 argv[3] = mapped; 1328 exit(pax_main(4, argv)); 1329 } 1330 break; 1331#endif 1332#ifdef WANT_GZIP 1333 case DO_GZONLY: 1334 if (mapped) 1335 free(mapped); 1336 if ((phile = open(mapped, O_RDONLY)) < 0) { 1337 control_printf(SL_FAILURE, "553 Error: %s.", strerror(errno)); 1338 return; 1339 } 1340 if (dataconn()) { 1341 if (mapped) 1342 free(mapped); 1343 return; 1344 } 1345 alarm(0); 1346 buffer = malloc(xfer_bufsize); 1347 /* check for alloc error */ 1348 if (! buffer) 1349 { 1350 bftpd_log("Memory error while sending file.", 0); 1351 control_printf(SL_FAILURE, "553 An unknown error occured on the server.", 0); 1352 if (phile) close(phile); 1353 return; 1354 } 1355 1356 /* check buffer size based on number of connections */ 1357 num_clients = bftpdutmp_usercount("*"); 1358 my_buffer_size = get_buffer_size(num_clients); 1359 /* Use "wb9" for maximum compression, uses more CPU time... */ 1360 gzfile = gzdopen(sock, "wb"); 1361 while ((i = read(phile, buffer, my_buffer_size))) { 1362 gzwrite(gzfile, buffer, i); 1363 test_abort(1, phile, sock); 1364 new_num_clients = bftpdutmp_usercount("*"); 1365 if ( new_num_clients != num_clients ) 1366 { 1367 num_clients = new_num_clients; 1368 my_buffer_size = get_buffer_size(num_clients); 1369 } 1370 /* pause between transfers */ 1371 if (xfer_delay) 1372 { 1373 wait_time.tv_sec = 0; 1374 wait_time.tv_usec = xfer_delay; 1375 select( 0, NULL, NULL, NULL, &wait_time); 1376 } 1377 } 1378 free(buffer); 1379 close(phile); 1380 gzclose(gzfile); 1381 break; 1382#endif 1383 1384#ifdef HAVE_ZLIB_H 1385 case DO_GZUNZIP: 1386 if ( dataconn() ) 1387 return; 1388 1389 gzfile = gzdopen(phile, "rb"); 1390 if (! gzfile) 1391 { 1392 close(phile); 1393 bftpd_log("Memory error while sending file.", 0); 1394 control_printf(SL_FAILURE, "553 An unknown error occured on the server.", 0); 1395 return; 1396 } 1397 1398 alarm(0); 1399 buffer = malloc(xfer_bufsize); 1400 if (! buffer) 1401 { 1402 close(phile); 1403 gzclose(gzfile); 1404 bftpd_log("Memory error while sending file.", 0); 1405 control_printf(SL_FAILURE, "553 An unknown error occured on the server.", 0); 1406 return; 1407 } 1408 1409 /* check buffer size based on number of connections */ 1410 num_clients = bftpdutmp_usercount("*"); 1411 my_buffer_size = get_buffer_size(num_clients); 1412 1413 i = gzread(gzfile, buffer, my_buffer_size); 1414 while ( i ) 1415 { 1416 write(sock, buffer, i); 1417 // test_abort(1, phile, sock); 1418 1419 new_num_clients = bftpdutmp_usercount("*"); 1420 if ( new_num_clients != num_clients ) 1421 { 1422 num_clients = new_num_clients; 1423 my_buffer_size = get_buffer_size(num_clients); 1424 } 1425 /* pause between transfers */ 1426 if (xfer_delay) 1427 { 1428 wait_time.tv_sec = 0; 1429 wait_time.tv_usec = xfer_delay; 1430 select( 0, NULL, NULL, NULL, &wait_time); 1431 } 1432 1433 i = gzread(gzfile, buffer, my_buffer_size); 1434 } // end of while not end of file 1435 1436 free(buffer); 1437 close(phile); 1438 gzclose(gzfile); 1439 break; // send file and unzip on the fly 1440#endif 1441 1442 case DO_NORMAL: 1443 /* 1444 FIXME:: We are freeing "mapped" twice. Commenting out 1445 if (mapped) 1446 free(mapped); 1447 */ 1448 if (dataconn()) 1449 return; 1450 alarm(0); 1451 lseek(phile, offset, SEEK_SET); 1452 offset = 0; 1453 buffer = malloc(xfer_bufsize * 2 + 1); 1454 /* make sure buffer was created */ 1455 if (! buffer) 1456 { 1457 control_printf(SL_FAILURE, "553 An unknown error occured."); 1458 bftpd_log("Memory error while trying to send file.", 0); 1459 close(sock); 1460 close(phile); 1461 return; 1462 } 1463 num_clients = bftpdutmp_usercount("*"); 1464 my_buffer_size = get_buffer_size(num_clients); 1465 while ((i = read(phile, buffer, my_buffer_size))) { 1466 if (test_abort(1, phile, sock)) { 1467 free(buffer); 1468 return; 1469 } 1470 1471 if (xfertype == TYPE_ASCII) { 1472 buffer[i] = '\0'; 1473 i += replace(buffer, "\n", "\r\n"); 1474 } 1475 send_status = send(sock, buffer, i, 0); 1476 /* Foxconn add start, Jonathan 10/14/2011 */ 1477 /* add dropped connection condition checking ,patched from v3.1 */ 1478 if (send_status < 0) 1479 { 1480 printf("426 Transfer aborted.\n"); 1481 free(buffer); 1482 close(phile); 1483 close(sock); 1484 alarm(control_timeout); 1485 control_printf(SL_SUCCESS, "426 Transfer aborted."); 1486 control_printf(SL_SUCCESS, "226 Aborted."); 1487 bftpd_log("File transmission interrupted. Send failed.\n"); 1488 return; 1489 } 1490 /* Foxconn add end, Jonathan 10/14/2011 */ 1491 1492 bytes_sent += i; 1493 1494 new_num_clients = bftpdutmp_usercount("*"); 1495 /* Foxconn modified start pling 12/30/2009 */ 1496 /* Change these params only if num of clients is changed */ 1497 if (new_num_clients != num_clients) 1498 { 1499 num_clients = new_num_clients; 1500 my_buffer_size = get_buffer_size(num_clients); 1501 } 1502 /* Foxconn modified end pling 12/30/2009 */ 1503 1504 /* pause between transfers */ 1505 if (xfer_delay) 1506 { 1507 wait_time.tv_sec = 0; 1508 wait_time.tv_usec = xfer_delay; 1509 select( 0, NULL, NULL, NULL, &wait_time); 1510 } 1511 1512 } // end of while 1513 free(buffer); 1514 } 1515 1516 close(phile); 1517 close(sock); 1518 offset = 0; 1519 alarm(control_timeout); 1520 control_printf(SL_SUCCESS, "226 File transmission successful."); 1521 bftpd_log("File transmission of '%s' successful.\n", filename); 1522 if (mapped) free(mapped); 1523} 1524 1525void do_dirlist(char *dirname, char verbose) 1526{ 1527 FILE *datastream; 1528 if (dirname[0] != '\0') { 1529 /* skip arguments */ 1530 if (dirname[0] == '-') { 1531 while ((dirname[0] != ' ') && (dirname[0] != '\0')) 1532 dirname++; 1533 if (dirname[0] != '\0') 1534 dirname++; 1535 } 1536 } 1537 if (dataconn()) 1538 return; 1539 alarm(0); 1540 datastream = fdopen(sock, "w"); 1541 if (dirname[0] == '\0') 1542 dirlist("*", datastream, verbose); 1543 else { 1544 char *mapped = bftpd_cwd_mappath(dirname); 1545 /* Foxconn added start pling 09/03/2012 */ 1546 /* WNDR4500v2 IR45/46/47, don't allow user to access outside /shares */ 1547 if (strncmp(mapped, "/mnt/usb", 8) != 0 && 1548 strncmp(mapped, "/shares", 7) != 0) 1549 { 1550 bftpd_log("Access to '%s' denied!\n", mapped); 1551 free(mapped); 1552 fclose(datastream); 1553 alarm(control_timeout); 1554 control_printf(SL_FAILURE, "550 Error: Access Denied."); 1555 return; 1556 } 1557 /* Foxconn added end pling 09/03/2012 */ 1558 dirlist(mapped, datastream, verbose); 1559 free(mapped); 1560 } 1561 fclose(datastream); 1562 alarm(control_timeout); 1563 control_printf(SL_SUCCESS, "226 Directory list has been submitted.%s:%d", user, verbose); 1564} 1565 1566void command_list(char *dirname) 1567{ 1568 do_dirlist(dirname, 1); 1569} 1570 1571void command_nlst(char *dirname) 1572{ 1573 do_dirlist(dirname, 0); 1574} 1575 1576void command_syst(char *params) 1577{ 1578 control_printf(SL_SUCCESS, "215 UNIX Type: L8"); 1579} 1580 1581void command_mdtm(char *filename) 1582{ 1583 struct stat statbuf; 1584 struct tm *filetime; 1585 char *fullfilename = bftpd_cwd_mappath(filename); 1586 1587 /* Foxconn added start pling 06/07/2010 */ 1588 /* BTS-A20102624: Chrome FTP fix: 1589 * handle the case where FTP client tries to access /shares/shares 1590 */ 1591 if (strncmp(filename,"/shares/shares", strlen("/shares/shares")) == 0) 1592 { 1593 if (stat(fullfilename, &statbuf)) 1594 { 1595 free(fullfilename); 1596 filename += strlen("/shares"); 1597 fullfilename = bftpd_cwd_mappath(filename); 1598 } 1599 } 1600 /* Foxconn added end pling 06/07/2010 */ 1601 1602 if (!stat(fullfilename, (struct stat *) &statbuf)) { 1603 filetime = gmtime((time_t *) & statbuf.st_mtime); 1604 control_printf(SL_SUCCESS, "213 %04i%02i%02i%02i%02i%02i", 1605 filetime->tm_year + 1900, filetime->tm_mon + 1, 1606 filetime->tm_mday, filetime->tm_hour, filetime->tm_min, 1607 filetime->tm_sec); 1608 } else { 1609 control_printf(SL_FAILURE, "550 Error while determining the modification time: %s", 1610 strerror(errno)); 1611 } 1612 free(fullfilename); 1613} 1614 1615void command_cwd(char *dir) 1616{ 1617 if (bftpd_cwd_chdir(dir)) { 1618 /* Foxconn modified start pling 05/14/2009 */ 1619 /* Deny access to root dir - '/' */ 1620 if (errno == EACCES) { 1621 bftpd_log("Error: 'Not allowed to chdir to /'.\n"); 1622 control_printf(SL_FAILURE, "550 Error: Access Denied."); 1623 } else { 1624 bftpd_log("Error: '%s' while changing directory to '%s'.\n", 1625 strerror(errno), dir); 1626 control_printf(SL_FAILURE, "451 Error: %s.", strerror(errno)); 1627 } 1628 /* Foxconn modified end pling 05/14/2009 */ 1629 } else { 1630 bftpd_log("Changed directory to '%s'.\n", dir); 1631 control_printf(SL_SUCCESS, "250 OK"); 1632 } 1633} 1634 1635void command_cdup(char *params) 1636{ 1637 bftpd_log("Changed directory to '..'.\n"); 1638 bftpd_cwd_chdir(".."); 1639 control_printf(SL_SUCCESS, "250 OK"); 1640} 1641 1642void command_dele(char *filename) 1643{ 1644 char *mapped = bftpd_cwd_mappath(filename); 1645 int fd; 1646 1647 /* Foxconn, added by MJ., 2010.07.07, for check if file is locked. */ 1648#ifdef LOCK_DEBUG 1649 printf("%s begins.\n", __FUNCTION__); 1650#endif 1651 /*FIXME: We have to check file lock before pre_write_script */ 1652 1653 fd = open(mapped, O_RDONLY); 1654 if (fd >= 0) /* file exists */ 1655 { 1656 struct flock lock; 1657 lock.l_type = F_WRLCK; 1658 lock.l_whence = SEEK_SET; 1659 lock.l_start = 0; 1660 lock.l_len = 0; 1661 if (!fcntl(fd, F_GETLK, &lock)) 1662 { 1663#ifdef LOCK_DEBUG 1664 printf("1.%s: l_type:%d\n", __FUNCTION__, lock.l_type); 1665#endif 1666 if (lock.l_type != F_UNLCK) // File is locked by other process 1667 { 1668 bftpd_log("Error: '%s' while trying to delete file '%s'.\n", 1669 strerror(errno), filename); 1670 control_printf(SL_FAILURE, "550 Error: File is read-only"); 1671 close(fd); /* make sure it is not open */ 1672 free(mapped); 1673 return; 1674 } 1675 } 1676 close(fd); 1677 } 1678 /* Foxconn, ended by MJ., 2010.07.07 */ 1679 1680 1681 if (pre_write_script) 1682 run_script(pre_write_script, mapped); 1683 1684 if (unlink(mapped)) { 1685 bftpd_log("Error: '%s' while trying to delete file '%s'.\n", 1686 strerror(errno), filename); 1687 control_printf(SL_FAILURE, "451 Error: %s.", strerror(errno)); 1688 } else { 1689 bftpd_log("Deleted file '%s'.\n", filename); 1690 control_printf(SL_SUCCESS, "200 OK"); 1691 } 1692 1693 if (post_write_script) 1694 run_script(post_write_script, mapped); 1695 1696 free(mapped); 1697} 1698 1699void command_mkd(char *dirname) 1700{ 1701 char *mapped = bftpd_cwd_mappath(dirname); 1702 1703 if (pre_write_script) 1704 run_script(pre_write_script, mapped); 1705 1706 if (mkdir(mapped, 0755)) { 1707 bftpd_log("Error: '%s' while trying to create directory '%s'.\n", 1708 strerror(errno), dirname); 1709 control_printf(SL_FAILURE, "451 Error: %s.", strerror(errno)); 1710 } else { 1711 bftpd_log("Created directory '%s'.\n", dirname); 1712 control_printf(SL_SUCCESS, "257 \"%s\" has been created.", dirname); 1713 } 1714 1715 if (post_write_script) 1716 run_script(post_write_script, mapped); 1717 1718 free(mapped); 1719} 1720 1721void command_rmd(char *dirname) 1722{ 1723 char *mapped = bftpd_cwd_mappath(dirname); 1724 if (pre_write_script) 1725 run_script(pre_write_script, mapped); 1726 1727 if (rmdir(mapped)) { 1728 bftpd_log("Error: '%s' while trying to remove directory '%s'.\n", strerror(errno), dirname); 1729 control_printf(SL_FAILURE, "451 Error: %s.", strerror(errno)); 1730 } else { 1731 bftpd_log("Removed directory '%s'.\n", dirname); 1732 control_printf(SL_SUCCESS, "250 OK"); 1733 } 1734 1735 if (post_write_script) 1736 run_script(post_write_script, mapped); 1737 free(mapped); 1738} 1739 1740void command_noop(char *params) 1741{ 1742 control_printf(SL_SUCCESS, "200 OK"); 1743} 1744 1745void command_rnfr(char *oldname) 1746{ 1747 FILE *file; 1748 char *mapped = bftpd_cwd_mappath(oldname); 1749 if ((file = fopen(mapped, "r"))) { 1750 fclose(file); 1751 if (philename) 1752 free(philename); 1753 philename = mapped; 1754 state = STATE_RENAME; 1755 control_printf(SL_SUCCESS, "350 File exists, ready for destination name"); 1756 } else { 1757 free(mapped); 1758 control_printf(SL_FAILURE, "451 Error: %s.", strerror(errno)); 1759 } 1760} 1761 1762void command_rnto(char *newname) 1763{ 1764 char *mapped = bftpd_cwd_mappath(newname); 1765 1766 if (pre_write_script) 1767 run_script(pre_write_script, mapped); 1768 1769 /* Foxconn added start pling 09/12/2012 */ 1770 /* WNDR4500v2 IR79: Don't allow user to rename /shares */ 1771 //if (strcmp(philename, "/shares") == 0) 1772// control_printf(SL_FAILURE, "550 Error: Access Denied."); 1773// else 1774 /* Foxconn added end pling 09/12/2012 */ 1775 1776 /* Foxconn added start lawrence 09/14/2012 */ 1777 /* WNDR4500v2 IR84 and IR79: Don't allow user to rename file outside /shares */ 1778 if (strncmp(philename, "/shares/",8)) 1779 control_printf(SL_FAILURE, "550 Error: Access Denied."); 1780 else 1781 /* Foxconn added end lawrence 09/14/2012 */ 1782 if (rename(philename, mapped)) { 1783 bftpd_log("Error: '%s' while trying to rename '%s' to '%s'.\n", 1784 strerror(errno), philename, bftpd_cwd_mappath(newname)); 1785 control_printf(SL_FAILURE, "451 Error: %s.", strerror(errno)); 1786 } else { 1787 bftpd_log("Successfully renamed '%s' to '%s'.\n", philename, bftpd_cwd_mappath(newname)); 1788 control_printf(SL_SUCCESS, "250 OK"); 1789 state = STATE_AUTHENTICATED; 1790 } 1791 1792 if (post_write_script) 1793 run_script(post_write_script, mapped); 1794 1795 free(philename); 1796 free(mapped); 1797 philename = NULL; 1798} 1799 1800void command_rest(char *params) 1801{ 1802 offset = strtoul(params, NULL, 10); 1803 control_printf(SL_SUCCESS, "350 Restarting at offset %i.", offset); 1804} 1805 1806void command_size(char *filename) 1807{ 1808 struct stat statbuf; 1809 char *mapped = bftpd_cwd_mappath(filename); 1810 1811 /* Foxconn added start pling 06/07/2010 */ 1812 /* BTS-A20102624: Chrome FTP fix: 1813 * handle the case where FTP client tries to access /shares/shares 1814 */ 1815 if (strncmp(filename,"/shares/shares", strlen("/shares/shares")) == 0) 1816 { 1817 if (stat(mapped, &statbuf)) 1818 { 1819 free(mapped); 1820 filename += strlen("/shares"); 1821 mapped = bftpd_cwd_mappath(filename); 1822 } 1823 } 1824 /* Foxconn added end pling 06/07/2010 */ 1825 1826 if (!stat(mapped, &statbuf)) { 1827 control_printf(SL_SUCCESS, "213 %i", (int) statbuf.st_size); 1828 } else { 1829 control_printf(SL_FAILURE, "550 Error: %s.", strerror(errno)); 1830 } 1831 free(mapped); 1832} 1833 1834void command_quit(char *params) 1835{ 1836 control_printf(SL_SUCCESS, "221 %s", config_getoption("QUIT_MSG")); 1837 /* Make sure we log user out. -- Jesse <slicer69@hotmail.com> */ 1838 bftpdutmp_end(); 1839 exit(0); 1840} 1841 1842void command_stat(char *filename) 1843{ 1844 char *mapped = bftpd_cwd_mappath(filename); 1845 control_printf(SL_SUCCESS, "213-Status of %s:", filename); 1846 bftpd_stat(mapped, stderr); 1847 control_printf(SL_SUCCESS, "213 End of Status."); 1848 free(mapped); 1849} 1850 1851/* SITE commands */ 1852 1853void command_chmod(char *params) 1854{ 1855 int permissions; 1856 char *mapped; 1857 char *my_string; 1858 1859 if (!strchr(params, ' ')) { 1860 control_printf(SL_FAILURE, "550 Usage: SITE CHMOD <permissions> <filename>"); 1861 return; 1862 } 1863 my_string = strdup(strchr(params, ' ') + 1); 1864 if (! my_string) 1865 { 1866 control_printf(SL_FAILURE, "550: An error occured on the server trying to CHMOD."); 1867 return; 1868 } 1869 /* mapped = bftpd_cwd_mappath(strdup(strchr(params, ' ') + 1)); */ 1870 mapped = bftpd_cwd_mappath(my_string); 1871 free(my_string); 1872 1873 if (pre_write_script) 1874 run_script(pre_write_script, mapped); 1875 1876 *strchr(params, ' ') = '\0'; 1877 sscanf(params, "%o", &permissions); 1878 if (chmod(mapped, permissions)) 1879 control_printf(SL_FAILURE, "Error: %s.", strerror(errno)); 1880 else { 1881 bftpd_log("Changed permissions of '%s' to '%o'.\n", mapped, 1882 permissions); 1883 control_printf(SL_SUCCESS, "200 CHMOD successful."); 1884 } 1885 if (post_write_script) 1886 run_script(post_write_script, mapped); 1887 1888 free(mapped); 1889} 1890 1891void command_chown(char *params) 1892{ 1893 char foo[MAXCMD + 1], owner[MAXCMD + 1], group[MAXCMD + 1], 1894 filename[MAXCMD + 1], *mapped; 1895 int uid, gid; 1896 if (!strchr(params, ' ')) { 1897 control_printf(SL_FAILURE, "550 Usage: SITE CHOWN <owner>[.<group>] <filename>"); 1898 return; 1899 } 1900 sscanf(params, "%[^ ] %s", foo, filename); 1901 if (strchr(foo, '.')) 1902 sscanf(foo, "%[^.].%s", owner, group); 1903 else { 1904 strcpy(owner, foo); 1905 group[0] = '\0'; 1906 } 1907 if (!sscanf(owner, "%i", &uid)) /* Is it a number? */ 1908 if (((uid = mygetpwnam(owner, passwdfile))) < 0) { 1909 control_printf(SL_FAILURE, "550 User '%s' not found.", owner); 1910 return; 1911 } 1912 if (!sscanf(group, "%i", &gid)) 1913 if (((gid = mygetpwnam(group, groupfile))) < 0) { 1914 control_printf(SL_FAILURE, "550 Group '%s' not found.", group); 1915 return; 1916 } 1917 mapped = bftpd_cwd_mappath(filename); 1918 if (pre_write_script) 1919 run_script(pre_write_script, mapped); 1920 1921 if (chown(mapped, uid, gid)) 1922 control_printf(SL_FAILURE, "550 Error: %s.", strerror(errno)); 1923 else { 1924 bftpd_log("Changed owner of '%s' to UID %i GID %i.\n", filename, uid, 1925 gid); 1926 control_printf(SL_SUCCESS, "200 CHOWN successful."); 1927 } 1928 if (post_write_script) 1929 run_script(post_write_script, mapped); 1930 free(mapped); 1931} 1932 1933void command_site(char *str) 1934{ 1935 const struct command subcmds[] = { 1936 {"chmod ", NULL, command_chmod, STATE_AUTHENTICATED}, 1937 {"chown ", NULL, command_chown, STATE_AUTHENTICATED}, 1938 {NULL, NULL, 0}, 1939 }; 1940 int i; 1941 if (!strcasecmp(config_getoption("ENABLE_SITE"), "no")) { 1942 control_printf(SL_FAILURE, "550 SITE commands are disabled."); 1943 return; 1944 } 1945 for (i = 0; subcmds[i].name; i++) { 1946 if (!strncasecmp(str, subcmds[i].name, strlen(subcmds[i].name))) { 1947 cutto(str, strlen(subcmds[i].name)); 1948 subcmds[i].function(str); 1949 return; 1950 } 1951 } 1952 control_printf(SL_FAILURE, "550 Unknown command: 'SITE %s'.", str); 1953} 1954 1955void command_auth(char *type) 1956{ 1957 control_printf(SL_FAILURE, "550 Not implemented yet\r\n"); 1958} 1959 1960/* Foxconn added start pling 09/16/2009 */ 1961void command_opts(char *params) 1962{ 1963 if (strcasecmp(params, "utf8 on") == 0) 1964 control_printf(SL_SUCCESS, "200 UTF8 ON"); 1965 else 1966 control_printf(SL_SUCCESS, "550 %s not implemented", params); 1967} 1968/* Foxconn added end pling 09/16/2009 */ 1969 1970/* Command parsing */ 1971 1972const struct command commands[] = { 1973 {"USER", "<sp> username", command_user, STATE_CONNECTED, 0}, 1974 {"PASS", "<sp> password", command_pass, STATE_USER, 0}, 1975 {"XPWD", "(returns cwd)", command_pwd, STATE_AUTHENTICATED, 1}, 1976 {"PWD", "(returns cwd)", command_pwd, STATE_AUTHENTICATED, 0}, 1977 {"TYPE", "<sp> type-code (A or I)", command_type, STATE_AUTHENTICATED, 0}, 1978 {"PORT", "<sp> h1,h2,h3,h4,p1,p2", command_port, STATE_AUTHENTICATED, 0}, 1979 {"EPRT", "<sp><d><net-prt><d><ip><d><tcp-prt><d>", command_eprt, STATE_AUTHENTICATED, 1}, 1980 {"PASV", "(returns address/port)", command_pasv, STATE_AUTHENTICATED, 0}, 1981 {"EPSV", "(returns address/post)", command_epsv, STATE_AUTHENTICATED, 1}, 1982 {"ALLO", "<sp> size", command_allo, STATE_AUTHENTICATED, 1}, 1983 {"STOR", "<sp> pathname", command_stor, STATE_AUTHENTICATED, 0}, 1984 {"APPE", "<sp> pathname", command_appe, STATE_AUTHENTICATED, 1}, 1985 {"RETR", "<sp> pathname", command_retr, STATE_AUTHENTICATED, 0}, 1986 {"LIST", "[<sp> pathname]", command_list, STATE_AUTHENTICATED, 0}, 1987 {"NLST", "[<sp> pathname]", command_nlst, STATE_AUTHENTICATED, 0}, 1988 {"SYST", "(returns system type)", command_syst, STATE_CONNECTED, 0}, 1989 {"MDTM", "<sp> pathname", command_mdtm, STATE_AUTHENTICATED, 1}, 1990 {"XCWD", "<sp> pathname", command_cwd, STATE_AUTHENTICATED, 1}, 1991 {"CWD", "<sp> pathname", command_cwd, STATE_AUTHENTICATED, 0}, 1992 {"XCUP", "(up one directory)", command_cdup, STATE_AUTHENTICATED, 1}, 1993 {"CDUP", "(up one directory)", command_cdup, STATE_AUTHENTICATED, 0}, 1994 {"DELE", "<sp> pathname", command_dele, STATE_AUTHENTICATED, 0}, 1995 {"XMKD", "<sp> pathname", command_mkd, STATE_AUTHENTICATED, 1}, 1996 {"MKD", "<sp> pathname", command_mkd, STATE_AUTHENTICATED, 0}, 1997 {"XRMD", "<sp> pathname", command_rmd, STATE_AUTHENTICATED, 1}, 1998 {"RMD", "<sp> pathname", command_rmd, STATE_AUTHENTICATED, 0}, 1999 {"NOOP", "(no operation)", command_noop, STATE_AUTHENTICATED, 0}, 2000 {"RNFR", "<sp> pathname", command_rnfr, STATE_AUTHENTICATED, 0}, 2001 {"RNTO", "<sp> pathname", command_rnto, STATE_RENAME, 0}, 2002 {"REST", "<sp> byte-count", command_rest, STATE_AUTHENTICATED, 1}, 2003 {"SIZE", "<sp> pathname", command_size, STATE_AUTHENTICATED, 1}, 2004 {"QUIT", "(close control connection)", command_quit, STATE_CONNECTED, 0}, 2005 {"HELP", "[<sp> command]", command_help, STATE_AUTHENTICATED, 0}, 2006 {"STAT", "<sp> pathname", command_stat, STATE_AUTHENTICATED, 0}, 2007 {"SITE", "<sp> string", command_site, STATE_AUTHENTICATED, 0}, 2008 {"FEAT", "(returns list of extensions)", command_feat, STATE_AUTHENTICATED, 0}, 2009 /* {"AUTH", "<sp> authtype", command_auth, STATE_CONNECTED, 0}, 2010 */ {"ADMIN_LOGIN", "(admin)", command_adminlogin, STATE_CONNECTED, 0}, 2011 {"MGET", "<sp> pathname", command_mget, STATE_AUTHENTICATED, 0}, 2012 {"MPUT", "<sp> pathname", command_mput, STATE_AUTHENTICATED, 0}, 2013 {"OPTS", "<sp> string <sp> val", command_opts, STATE_AUTHENTICATED, 0}, // Foxconn added pling 09/16/2009 2014 {NULL, NULL, NULL, 0, 0} 2015}; 2016 2017void command_feat(char *params) 2018{ 2019 int i; 2020 control_printf(SL_SUCCESS, "211-Extensions supported:"); 2021 for (i = 0; commands[i].name; i++) 2022 if (commands[i].showinfeat) 2023 control_printf(SL_SUCCESS, " %s", commands[i].name); 2024 control_printf(SL_SUCCESS, " UTF8"); // Foxconn added pling 09/16/2009 2025 control_printf(SL_SUCCESS, "211 End"); 2026} 2027 2028void command_help(char *params) 2029{ 2030 int i; 2031 if (params[0] == '\0') { 2032 control_printf(SL_SUCCESS, "214-The following commands are recognized."); 2033 for (i = 0; commands[i].name; i++) 2034 control_printf(SL_SUCCESS, "214-%s", commands[i].name); 2035 control_printf(SL_SUCCESS, "214 End of help"); 2036 } else { 2037 for (i = 0; commands[i].name; i++) 2038 if (!strcasecmp(params, commands[i].name)) 2039 control_printf(SL_SUCCESS, "214 Syntax: %s", commands[i].syntax); 2040 } 2041} 2042 2043int parsecmd(char *str) 2044{ 2045 int i; 2046 char *p, *pp, confstr[18]; /* strlen("ALLOWCOMMAND_XXXX") + 1 == 18 */ 2047 p = pp = str; /* Remove garbage in the string */ 2048 while (*p) 2049 if ((unsigned char) *p < 32) 2050 p++; 2051 else 2052 *pp++ = *p++; 2053 *pp++ = 0; 2054 for (i = 0; commands[i].name; i++) { /* Parse command */ 2055 if (!strncasecmp(str, commands[i].name, strlen(commands[i].name))) { 2056 sprintf(confstr, "ALLOWCOMMAND_%s", commands[i].name); 2057 if (!strcasecmp(config_getoption(confstr), "no")) { 2058 bftpd_log("550 The command '%s' is disabled.\n", 2059 commands[i].name); 2060 /* Foxconn modified start pling 06/25/2009 */ 2061 /* Change the message sent to FTP client, as 2062 * specified by Netgear. 2063 */ 2064 if (!strcmp(commands[i].name, "DELE") || 2065 !strcmp(commands[i].name, "STOR") || 2066 !strcmp(commands[i].name, "MKD") || 2067 !strcmp(commands[i].name, "RMD") || 2068 !strcmp(commands[i].name, "XMKD") || 2069 !strcmp(commands[i].name, "XRMD")) 2070 control_printf(SL_FAILURE, "550 Read Only"); 2071 else 2072 control_printf(SL_FAILURE, "550 The command '%s' is disabled.", 2073 commands[i].name); 2074 /* Foxconn modified end pling 06/25/2009 */ 2075 return 1; 2076 } 2077 cutto(str, strlen(commands[i].name)); 2078 p = str; 2079 while ((*p) && ((*p == ' ') || (*p == '\t'))) 2080 p++; 2081 memmove(str, p, strlen(str) - (p - str) + 1); 2082 if (state >= commands[i].state_needed) { 2083 commands[i].function(str); 2084 return 0; 2085 } else { 2086 switch (state) { 2087 case STATE_CONNECTED: { 2088 control_printf(SL_FAILURE, "503 USER expected."); 2089 return 1; 2090 } 2091 case STATE_USER: { 2092 control_printf(SL_FAILURE, "503 PASS expected."); 2093 return 1; 2094 } 2095 case STATE_AUTHENTICATED: { 2096 control_printf(SL_FAILURE, "503 RNFR before RNTO expected."); 2097 return 1; 2098 } 2099 } 2100 } 2101 } 2102 } 2103 control_printf(SL_FAILURE, "500 Unknown command: \"%s\"", str); 2104 return 0; 2105} 2106 2107 2108int get_buffer_size(int num_connections) 2109{ 2110 int buffer_size; 2111 2112 if (num_connections < 1) 2113 num_connections = 1; 2114 2115 buffer_size = xfer_bufsize / num_connections; 2116 if ( buffer_size < 2) 2117 buffer_size = 2; 2118 2119 return buffer_size; 2120} 2121 2122 2123 2124/* 2125 This function forks and runs a script. On success it 2126 returns TRUE, if an error occures, it returns FALSE. 2127 */ 2128int run_script(char *script, char *path) 2129{ 2130 pid_t process_id; 2131 char *command_args[] = { script, path, NULL } ; 2132 sighandler_t save_quit, save_int, save_chld; 2133 2134 /* save original signal handler values */ 2135 save_quit = signal(SIGQUIT, SIG_IGN); 2136 save_int = signal(SIGINT, SIG_IGN); 2137 save_chld = signal(SIGCHLD, SIG_DFL); 2138 2139 process_id = fork(); 2140 /* check for failure */ 2141 if (process_id < 0) 2142 { 2143 signal(SIGQUIT, save_quit); 2144 signal(SIGINT, save_int); 2145 signal(SIGCHLD, save_chld); 2146 return FALSE; 2147 } 2148 2149 /* child process */ 2150 if (process_id == 0) 2151 { 2152 signal(SIGQUIT, SIG_DFL); 2153 signal(SIGINT, SIG_DFL); 2154 signal(SIGCHLD, SIG_DFL); 2155 2156 execv(script, command_args); 2157 bftpd_log("Error trying to run script: %s\n", script); 2158 exit(127); 2159 } 2160 2161 /* parent process */ 2162 do 2163 { 2164 process_id = wait4(process_id, NULL, 0, NULL); 2165 } while ( (process_id == -1) && (errno == EINTR) ); 2166 2167 signal(SIGQUIT, save_quit); 2168 signal(SIGINT, save_int); 2169 signal(SIGCHLD, save_chld); 2170 2171 return TRUE; 2172} 2173 2174