1/* 2 3bftpd Copyright (C) 1999-2003 Max-Wilhelm Bruker 4 5This program is is free software; you can redistribute it and/or modify 6it under the terms of the GNU General Public License, version 2 of the 7License as published by the Free Software Foundation. 8 9This program is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12GNU General Public License for more details. 13 14*/ 15 16#include <config.h> 17#include <stdio.h> 18#ifdef HAVE_SYS_TYPES_H 19#include <sys/types.h> 20#endif 21#ifdef HAVE_SYS_STAT_H 22#include <sys/stat.h> 23#endif 24#ifdef HAVE_SYS_SOCKET_H 25#include <sys/socket.h> 26#endif 27#ifdef HAVE_NETINET_IN_H 28#include <netinet/in.h> 29#endif 30#ifdef HAVE_ARPA_INET_H 31#include <arpa/inet.h> 32#endif 33#ifdef HAVE_ASM_SOCKET_H 34#include <asm/socket.h> 35#endif 36#include <signal.h> 37#include <string.h> 38#include <stdlib.h> 39#include <netdb.h> 40#include <unistd.h> 41#include <errno.h> 42#include <fcntl.h> 43#ifdef HAVE_WAIT_H 44# include <wait.h> 45#else 46# ifdef HAVE_SYS_WAIT_H 47# include <sys/wait.h> 48# endif 49#endif 50 51#include "main.h" 52#include "cwd.h" 53#include "mystring.h" 54#include "logging.h" 55#include "dirlist.h" 56#include "bftpdutmp.h" 57#include "options.h" 58#include "login.h" 59#include "list.h" 60 61#ifdef MAX_USB_ACCESS 62/* Foxconn, added by MJ., 2010.03.25, for making a shared memory. */ 63#ifndef LINUX26 64#include <linux/spinlock.h> 65#endif 66#include <sys/shm.h> 67#include <sys/stat.h> 68#define MAX_CON_NUM 15 69typedef struct 70{ 71 int sem_id; //ID of Semaphore, for data sync. 72 int num; //The number of total connections. 73 int ftp_num; //The number of ftp connections without pure WAN ftp.. 74 int wan_ftp_num; //The number of pure WAN ftp connections. 75}CON_STATISTIC; 76 77static int segment_id; 78static CON_STATISTIC *con_st; 79/* Foxconn, ended by MJ., 2010.03.25, */ 80 81/* Foxconn added start by Jenny Zhao, 06/10/2011 @USB log */ 82char client_ip[32]; 83int g_isLanIp; 84 85/* Foxconn added end by Jenny Zhao, 06/10/2011 */ 86 87/* Foxconn, added by MJ., 2010.03.25, for making a Semaphore. */ 88 89#include <sys/ipc.h> 90#include <sys/sem.h> 91#include <sys/types.h> 92#include <sys/wait.h> 93 94/* We must define union semun ourselves for using Semaphore. */ 95union semun { 96 int val; 97 struct semid_ds *buf; 98 unsigned short int *array; 99 struct seminfo *__buf; 100}; 101 102/* Obtain a binary semaphore��s ID, allocating if necessary. */ 103int binary_semaphore_allocation (key_t key, int sem_flags) 104{ 105 return semget (key, 1, sem_flags); 106} 107/* Deallocate a binary semaphore. All users must have finished their 108use. Returns -1 on failure. */ 109int binary_semaphore_deallocate (int semid) 110{ 111 union semun ignored_argument; 112 return semctl (semid, 1, IPC_RMID, ignored_argument); 113} 114 115/* Initialize a binary semaphore with a value of 1. */ 116int binary_semaphore_initialize (int semid) 117{ 118 union semun argument; 119 unsigned short values[1]; 120 values[0] = 1; 121 argument.array = values; 122 return semctl (semid, 0, SETALL, argument); 123} 124/* Wait on a binary semaphore. Block until the semaphore value is positive, then 125decrement it by 1. */ 126int binary_semaphore_wait (int semid) 127{ 128 struct sembuf operations[1]; 129 /* Use the first (and only) semaphore. */ 130 operations[0].sem_num = 0; 131 /* Decrement by 1. */ 132 operations[0].sem_op = -1; 133 /* Permit undo��ing. */ 134 operations[0].sem_flg = SEM_UNDO; 135 return semop (semid, operations, 1); 136} 137 138/* Post to a binary semaphore: increment its value by 1. 139This returns immediately. */ 140int binary_semaphore_post (int semid) 141{ 142 struct sembuf operations[1]; 143 /* Use the first (and only) semaphore. */ 144 operations[0].sem_num = 0; 145 /* Increment by 1. */ 146 operations[0].sem_op = 1; 147 /* Permit undo��ing. */ 148 operations[0].sem_flg = SEM_UNDO; 149 return semop (semid, operations, 1); 150} 151/* Foxconn, ened by MJ., 2010.03.29 */ 152#else 153char client_ip[32]; 154int g_isLanIp; 155#endif /* End of MAX_USB_ACCESS */ 156 157int global_argc; 158char **global_argv; 159char **my_argv_list; // jesse 160struct sockaddr_in name; 161int isparent = 1; 162int listensocket, sock; 163FILE *passwdfile = NULL, *groupfile = NULL, *devnull; 164struct sockaddr_in remotename; 165char *remotehostname; 166int control_timeout, data_timeout; 167int alarm_type = 0; 168 169struct bftpd_list_element *child_list; 170 171/* Command line parameters */ 172char *configpath = PATH_BFTPD_CONF; 173int daemonmode = 0; 174 175int all_no_password = 0; // Foxconn added pling 06/10/2009 176 177int inc_conn_num(); 178int dec_conn_num(); 179 180void print_file (int number, char *filename) 181{ 182 FILE *phile; 183 char foo[256]; 184 185 phile = fopen (filename, "r"); 186 if (phile) 187 { 188 while (fgets (foo, sizeof (foo), phile)) 189 { 190 foo[strlen (foo) - 1] = '\0'; 191 control_printf (SL_SUCCESS, "%i-%s", number, foo); 192 } 193 fclose (phile); 194 } 195} 196 197void end_child () 198{ 199 printf("end_child invoked for child (%d).\n", getpid()); 200 /* Foxconn, added by MJ., 2010.04.29, for connections counting. */ 201/* if(con_st != NULL) 202 { 203 binary_semaphore_wait(con_st->sem_id); 204 --(con_st->num); 205 binary_semaphore_post(con_st->sem_id); 206#ifdef CON_DEBUG 207 printf("->total con num: %d, by bftpd\n", 208 con_st->num); 209#endif 210 }*/ 211 /* Foxconn, ended by MJ., 2010.04.29. */ 212 213 if (passwdfile) 214 fclose (passwdfile); 215 if (groupfile) 216 fclose (groupfile); 217 config_end (); 218 bftpd_log ("Quitting.\n"); 219 bftpd_statuslog (1, 0, "quit"); 220 bftpdutmp_end (); 221 log_end (); 222 login_end (); 223 bftpd_cwd_end (); 224 if (daemonmode) 225 { 226 close (sock); 227 close (0); 228 close (1); 229 close (2); 230 } 231 232 /* Foxconn added start pling 09/14/2013 */ 233 /* This was done in SIGCHLD handler before. 234 * Now since we fork twice, we decrement counter here. 235 */ 236#ifdef MAX_USB_ACCESS 237 dec_conn_num(); 238#endif 239 /* Foxconn added end pling 09/14/2013 */ 240} 241 242 243 244/* 245This function causes the program to 246re-read parts of the config file. 247 248-- Jesse 249*/ 250void handler_sighup (int sig) 251{ 252 bftpd_log("%s.\n", __FUNCTION__); 253 /* Foxconn, added by MJ., 2010.04.29, for connections counting. */ 254 /*if(con_st != NULL) 255 { 256 binary_semaphore_wait(con_st->sem_id); 257 --(con_st->num); 258 binary_semaphore_post(con_st->sem_id); 259#ifdef CON_DEBUG 260 printf("->total con num: %d, by bftpd\n", 261 con_st->num); 262#endif 263 }*/ 264 /* Foxconn, ended by MJ., 2010.04.29. */ 265 bftpd_log ("Caught HUP signal. Re-reading config file.\n"); 266 Reread_Config_File (); 267 signal (sig, handler_sighup); 268} 269 270 271 272 273void handler_sigchld (int sig) 274{ 275 pid_t pid; 276 int i; 277 struct bftpd_childpid *childpid; 278 279 bftpd_log("%s\n", __FUNCTION__); 280 281 /* Foxconn, added by MJ., 2010.03.30, for connections counting. */ 282#if 0 //def MAX_USB_ACCESS_OLD // compiler flag is not used 283 if(con_st != NULL) 284 { 285 FILE *pfp; 286 int bftpd_pid; 287 int wan_ftp = 0; 288 if ((pfp = fopen ("/var/run/bftpd_wan.pid", "r"))) 289 { 290 char tmp[32]; 291 fgets(tmp, 80, pfp); 292 bftpd_pid = atoi(tmp); 293 if((getpid() == bftpd_pid)) 294 wan_ftp = 1; 295 fclose(pfp); 296 } 297 binary_semaphore_wait(con_st->sem_id); 298 if(con_st->num > 0) 299 { 300 --(con_st->num); 301 if(wan_ftp) 302 --(con_st->wan_ftp_num); 303 else 304 --(con_st->ftp_num); 305 } 306 binary_semaphore_post(con_st->sem_id); 307#ifdef CON_DEBUG 308 printf("->total con num: %d, by bftpd\n", con_st->num); 309#endif 310 } 311#endif // End of MAX_USB_ACCESS 312 /* Foxconn, ended by MJ., 2010.03.30. */ 313 314 315 /* Get the child's return code so that the zombie dies */ 316 /*Foxconn modify start by Hank 10/01/2013*/ 317 // pid = wait (NULL); 318 pid = waitpid(-1, NULL, WNOHANG); 319 320 while (pid > 0) 321 /*Foxconn modify end by Hank 10/01/2013*/ 322 { 323 for (i = 0; i < bftpd_list_count (child_list); i++) 324 { 325 childpid = bftpd_list_get (child_list, i); 326 if (childpid->pid == pid) 327 { 328 close (childpid->sock); 329 bftpd_list_del (&child_list, i); 330 free (childpid); 331 /* make sure the child is removed from the log */ 332 bftpdutmp_remove_pid (pid); 333#ifdef MAX_USB_ACCESS 334 dec_conn_num(); 335#endif 336 } 337 /*Foxconn modify start by Hank 10/01/2013*/ 338 } 339 pid = waitpid(-1, NULL, WNOHANG); /* check for more children */ 340 /*Foxconn modify end by Hank 10/01/2013*/ 341 } 342} 343 344void handler_sigterm (int signum) 345{ 346 bftpd_log ("%s.\n", __FUNCTION__); 347 /* Foxconn, added by MJ., 2010.04.29, for connections counting. */ 348/* if(con_st != NULL) 349 { 350 binary_semaphore_wait(con_st->sem_id); 351 //if(con_st->ftp_num != 0) 352 (con_st->num) = (con_st->num) -100; 353 binary_semaphore_post(con_st->sem_id); 354#ifdef CON_DEBUG 355 printf("->total con num: %d, by bftpd\n", 356 con_st->num); 357#endif 358 }*/ 359 /* Foxconn, ended by MJ., 2010.04.29. */ 360 361 362 bftpdutmp_end (); 363 exit (0); /* Force normal termination so that end_child() is called */ 364} 365 366void handler_sigalrm (int signum) 367{ 368 printf("%s:\n", __FUNCTION__); 369 /* Log user out. -- Jesse <slicer69@hotmail.com> */ 370 bftpdutmp_end (); 371 372 /* Foxconn, added by MJ., 2010.03.30, for connections counting. */ 373/* if(con_st != NULL) 374 { 375 binary_semaphore_wait(con_st->sem_id); 376 --(con_st->num); 377 binary_semaphore_post(con_st->sem_id); 378#ifdef CON_DEBUG 379 printf("->total con num: %d, by bftpd\n", con_st->num); 380#endif 381 }*/ 382 /* Foxconn, ended by MJ., 2010.03.30. */ 383 384 if (alarm_type) 385 { 386 close (alarm_type); 387 388 bftpd_log 389 ("Kicked from the server due to data connection timeout.\n"); 390 control_printf (SL_FAILURE, 391 "421 Kicked from the server due to data connection timeout."); 392 exit (0); 393 } 394 else 395 { 396 bftpd_log 397 ("Kicked from the server due to control connection timeout.\n"); 398 control_printf (SL_FAILURE, 399 "421 Kicked from the server due to control connection timeout."); 400 exit (0); 401 } 402} 403 404void init_everything () 405{ 406 if (!daemonmode) 407 { 408 config_init (); 409 hidegroups_init (); 410 } 411 log_init (); 412 bftpdutmp_init (); 413 login_init (); 414} 415 416#ifdef MAX_USB_ACCESS 417int dec_conn_num() 418{ 419 if(con_st != NULL) 420 { 421 FILE *pfp; 422 int bftpd_pid; 423 int wan_ftp = 0; 424 if ((pfp = fopen ("/var/run/bftpd_wan.pid", "r"))) 425 { 426 char tmp[32]; 427 fgets(tmp, 80, pfp); 428 bftpd_pid = atoi(tmp); 429 if((getpid() == bftpd_pid)) 430 wan_ftp = 1; 431 fclose(pfp); 432 } 433 binary_semaphore_wait(con_st->sem_id); 434 if(con_st->num > 0) 435 { 436 --(con_st->num); 437 if(wan_ftp) 438 --(con_st->wan_ftp_num); 439 else 440 --(con_st->ftp_num); 441 } 442 binary_semaphore_post(con_st->sem_id); 443//#ifdef CON_DEBUG 444 //cprintf("->total con num: %d, by bftpd\n", con_st->num); 445//#endif 446 } 447 /* Foxconn, ended by MJ., 2010.03.30. */ 448} 449 450int inc_conn_num () 451{ 452 if(con_st != NULL) 453 { 454 FILE *pfp; 455 int bftpd_pid; 456 int wan_ftp = 0; 457 458 if ((pfp = fopen ("/var/run/bftpd_wan.pid", "r"))) 459 { 460 char tmp[32]; 461 fgets(tmp, 80, pfp); 462 bftpd_pid = atoi(tmp); 463 if((getppid() == bftpd_pid)) 464 wan_ftp = 1; 465 fclose(pfp); 466 } 467 binary_semaphore_wait(con_st->sem_id); 468 if(con_st->num >= MAX_CON_NUM){ 469 ++(con_st->num); 470 if(wan_ftp) 471 ++(con_st->wan_ftp_num); 472 else 473 ++(con_st->ftp_num); 474 printf("The Connections are over 15.\n"); 475 binary_semaphore_post(con_st->sem_id); 476 return 0; 477 } 478 479 ++(con_st->num); 480 if(wan_ftp) 481 ++(con_st->wan_ftp_num); 482 else 483 ++(con_st->ftp_num); 484 binary_semaphore_post(con_st->sem_id); 485//#ifdef CON_DEBUG 486 //cprintf("->total con num: %d, by bftpd.\n", con_st->num); 487//#endif 488 return 1; 489 } 490 return 0; 491} 492#endif 493 494int main (int argc, char **argv) 495{ 496 char str[MAXCMD + 1]; 497 static struct hostent *he; 498 int i = 1, port; 499 int retval; 500 int over_limit = 0; 501 socklen_t my_length; 502 FILE *pid_fp;/* Foxconn add, Jasmine Yang, 09/13/2007 */ 503 extern int cur_conn; 504 505 my_argv_list = argv; 506 signal (SIGHUP, handler_sighup); 507 508 /* Foxconn, added by MJ., 2010.03.25, for count the totoal connections 509 * of accessing USB dir. 510 */ 511#ifdef MAX_USB_ACCESS 512 FILE *shmid_fp = fopen("/tmp/shm_id", "r"); 513 if(shmid_fp != NULL) 514 { 515 fscanf(shmid_fp, "%d", &segment_id); 516 printf("bftpd: segment_id:%d\n", segment_id); 517 fclose(shmid_fp); 518 } 519 else{ 520 printf("/tmp/shm_id open failed.\n"); 521 segment_id = -1; 522 //exit(1); 523 } 524 /* attach the shared memory segment, at a different address. */ 525 /*Foxconn modify start by Hank 10/01/2013*/ 526 if(segment_id != -1) 527 { 528 //con_st = (CON_STATISTIC*) shmat (segment_id, (void*) 0x5000000, 0); 529 con_st = (CON_STATISTIC*) shmat (segment_id, NULL, 0); 530 531 if(con_st != -1) 532 { 533 printf ("shared memory reattached at address %p\n", con_st); 534 con_st->ftp_num = 0; 535 } 536 else 537 { 538 con_st = NULL; 539 printf ("shared memory reattached failed\n"); 540 } 541 } 542 else 543 { 544 /*Foxconn modify end by Hank 10/01/2013*/ 545 con_st = NULL; 546 printf ("fail to get shared memory reattached at address \n"); 547 } 548#endif // End of MAX_USB_ACCESS 549 /*Foxconn, ended by MJ., 2010.03.25*/ 550 551 552 553 554 while (((retval = getopt (argc, argv, "c:hdDin"))) > -1) 555 { 556 switch (retval) 557 { 558 case 'h': 559 printf ("Usage: %s [-h] [-i|-d|-D] [-c <filename>|-n]\n" 560 "-h print this help\n" "-i (default) run from inetd\n" 561 "-d daemon mode: fork() and run in TCP listen mode\n" 562 "-D run in TCP listen mode, but don't pre-fork()\n" 563 "-c read the config file named \"filename\" instead of " 564 PATH_BFTPD_CONF "\n" "-n no config file, use defaults\n", 565 argv[0]); 566 return 0; 567 case 'i': 568 daemonmode = 0; 569 break; 570 case 'd': 571 daemonmode = 1; 572 break; 573 case 'D': 574 daemonmode = 2; 575 break; 576 case 'c': 577 configpath = strdup (optarg); 578 break; 579 case 'n': 580 configpath = NULL; 581 break; 582 } 583 } 584 if (daemonmode) 585 { 586 struct sockaddr_in myaddr, new; 587 588 if (daemonmode == 1) 589 { 590 if (fork ()) 591 exit (0); /* Exit from parent process */ 592 setsid (); 593 if (fork ()) 594 return 0; 595/* Foxconn add start, Jasmine Yang, 09/13/2007 */ 596 if (!(pid_fp = fopen ("/var/run/bftpd.pid", "w"))) 597 { 598 perror ("/var/run/bftpd.pid"); 599 return 0; 600 } 601 fprintf (pid_fp, "%d", getpid ()); 602 fclose (pid_fp); 603/* Foxconn add end, Jasmine Yang, 09/13/2007 */ 604 } 605 signal (SIGCHLD, handler_sigchld); 606 607//#ifndef QUICK_FIX_ISSUES //@ftpRW : we need this 608//FIXME 609 config_init (); 610//#endif 611 chdir ("/"); 612 hidegroups_init (); 613 listensocket = socket (AF_INET, SOCK_STREAM, 0); 614#ifdef SO_REUSEADDR 615 setsockopt (listensocket, SOL_SOCKET, SO_REUSEADDR, (void *) &i, 616 sizeof (i)); 617#endif 618#ifdef SO_REUSEPORT 619 setsockopt (listensocket, SOL_SOCKET, SO_REUSEPORT, (void *) &i, 620 sizeof (i)); 621#endif 622 memset ((void *) &myaddr, 0, sizeof (myaddr)); 623 if (!((port = strtoul (config_getoption ("PORT"), NULL, 10)))) 624 port = DEFAULT_PORT; 625 myaddr.sin_port = htons (port); 626 if (!strcasecmp (config_getoption ("BIND_TO_ADDR"), "any") 627 || !config_getoption ("BIND_TO_ADDR")[0]) 628 myaddr.sin_addr.s_addr = INADDR_ANY; 629 else{ 630 char file_path[256]; 631 FILE *pfp; 632 633 myaddr.sin_addr.s_addr = 634 inet_addr (config_getoption ("BIND_TO_ADDR")); 635 636 printf("write pid:%d tp /var/run/bftpd_wan.pid.\n", getpid()); 637 638 if (!(pfp = fopen ("/var/run/bftpd_wan.pid", "w"))) 639 { 640 perror ("/var/run/bftpd_wan.pid"); 641 return 0; 642 } 643 fprintf (pfp, "%d", getpid ()); 644 fclose (pfp); 645 } 646 if (bind (listensocket, (struct sockaddr *) &myaddr, sizeof (myaddr)) 647 < 0) 648 { 649 fprintf (stderr, "Bind failed: %s\n", strerror (errno)); 650 exit (1); 651 } 652 else 653 printf("bftpd: socket bound in %s:%d\n", inet_ntoa(myaddr.sin_addr), port); 654 655 if (listen (listensocket, 1)) 656 { 657 fprintf (stderr, "Listen failed: %s\n", strerror (errno)); 658 exit (1); 659 } 660 661 for (i = 0; i < 3; i++) 662 { 663 close (i); /* Remove fd pointing to the console */ 664 open ("/dev/null", O_RDWR); /* Create fd pointing nowhere */ 665 } 666 667 my_length = sizeof (new); 668 while ((sock = 669 accept (listensocket, (struct sockaddr *) &new, &my_length))) 670 { 671 pid_t pid; 672 673 over_limit = 0; 674 675 /* Foxconn added start by Jenny Zhao, 06/13/2011 @USB log */ 676 strcpy(client_ip, inet_ntoa(new.sin_addr)); 677 g_isLanIp = isLanSubnet(client_ip); 678 /* Foxconn added end by Jenny Zhao, 06/13/2011 */ 679 680#ifdef MAX_USB_ACCESS 681 /* Foxconn, CSWang, limit 15 connection */ 682 /* printf("cur conn:%d %d\n", cur_conn, bftpd_list_count( &child_list) ); */ 683 if ( cur_conn > MAX_CON_NUM ) { 684 close(sock); 685 continue; 686 } 687 688 if(con_st != NULL) 689 { 690 printf("curconn:%d\n", con_st->num); 691 if ( con_st->num >= MAX_CON_NUM ) { 692 //if ( con_st->num >= 3 ) { 693 close(sock); 694 /* printf("over 15 connection"); */ 695 //sleep(1); 696 over_limit = 1; 697 } 698 699 if( over_limit ) { 700 over_limit = 0; 701 continue; 702 } 703 } 704#endif 705 /* If accept() becomes interrupted by SIGCHLD, it will return -1. 706 * So in order not to create a child process when that happens, 707 * we have to check if accept() returned an error. 708 */ 709 if (sock > 0) 710 { 711 /* Foxconn modified start pling 09/14/2013 */ 712 /* Avoid zombie ftp process, by fork twice */ 713 int pid2; 714 int status; 715 716 pid = fork (); 717 if (!pid) 718 { /* child */ 719 pid2 = fork(); 720 if (!pid2) 721 { 722 close (0); 723 close (1); 724 close (2); 725 isparent = 0; 726 dup2 (sock, fileno (stdin)); 727 dup2 (sock, fileno (stderr)); 728 break; 729 } 730 else 731 exit(0); 732 } 733 else 734 { /* parent */ 735 struct bftpd_childpid *tmp_pid; 736 pid_t ret; 737 738 ret = waitpid(pid, &status, 0); 739 if (WIFEXITED(status)) 740 printf("child %d WIFEXITED\n", pid); 741 if (WEXITSTATUS(status)) 742 printf("child %d WEXITSTATUS\n", pid); 743 if (WIFSIGNALED(status)) 744 printf("child %d WIFSIGNALED\n", pid); 745 if (WTERMSIG(status)) 746 printf("child %d WTERMSIG\n", pid); 747 if (WCOREDUMP(status)) 748 printf("child %d WCOREDUMP\n", pid); 749 if (WIFSTOPPED(status)) 750 printf("child %d WIFSTOPPED\n", pid); 751 if (WSTOPSIG(status)) 752 printf("child %d WSTOPSIG\n", pid); 753 if (WIFCONTINUED(status)) 754 printf("child %d WIFCONTINUED\n", pid); 755 756#if 0 /* don't need to keep child pid anymore */ 757 tmp_pid = malloc (sizeof (struct bftpd_childpid)); 758 tmp_pid->pid = pid; 759 tmp_pid->sock = sock; 760 bftpd_list_add (&child_list, tmp_pid); 761#endif 762 if (ret != pid) 763 perror("waitpid"); 764 close(sock); /* parent don't need this 'accept' socket, leave it to client */ 765#ifdef MAX_USB_ACCESS 766 inc_conn_num(); 767#endif 768 } 769 } 770 /* Foxconn modified end pling 09/14/2013 */ 771 } 772 } 773 774 /* Child only. From here on... */ 775 776 //Foxconn modify, Jasmine Yang, 09/12/2007 777 //devnull = fopen ("/dev/null", "w"); 778 devnull = fopen ("/dev/console", "w"); 779 global_argc = argc; 780 global_argv = argv; 781 init_everything (); 782 783 atexit (end_child); 784 785 /* Foxconn, added by MJ., 2010.03.25, for count the totoal connections 786 * of accessing USB dir. 787 */ 788#if 0 //def MAX_USB_ACCESS_OLD // compiler flag is not used 789 if(con_st != NULL) 790 { 791 FILE *pfp; 792 int bftpd_pid; 793 int wan_ftp = 0; 794 795 if ((pfp = fopen ("/var/run/bftpd_wan.pid", "r"))) 796 { 797 char tmp[32]; 798 fgets(tmp, 80, pfp); 799 bftpd_pid = atoi(tmp); 800 if((getppid() == bftpd_pid)) 801 wan_ftp = 1; 802 fclose(pfp); 803 } 804 binary_semaphore_wait(con_st->sem_id); 805 if(con_st->num >= MAX_CON_NUM){ 806 ++(con_st->num); 807 if(wan_ftp) 808 ++(con_st->wan_ftp_num); 809 else 810 ++(con_st->ftp_num); 811 printf("The Connections are over 15.\n"); 812 binary_semaphore_post(con_st->sem_id); 813 goto exit; 814 } 815 816 ++(con_st->num); 817 if(wan_ftp) 818 ++(con_st->wan_ftp_num); 819 else 820 ++(con_st->ftp_num); 821 binary_semaphore_post(con_st->sem_id); 822#ifdef CON_DEBUG 823 printf("->total con num: %d, by bftpd.\n", con_st->num); 824#endif 825 } 826#endif // End of MAX_USB_ACCESS 827 /* Foxconn, ended by MJ., 2010.03.25 */ 828 829 //atexit (end_child); 830 signal (SIGTERM, handler_sigterm); 831 signal (SIGALRM, handler_sigalrm); 832 833 834 /* If we do not have getpwnam() for some reason, then 835 we must use FILE_AUTH or exit. */ 836#ifdef NO_GETPWNAM 837 { 838 char *file_auth_option; 839 840 file_auth_option = config_getoption ("FILE_AUTH"); 841 if (!file_auth_option[0]) 842 { 843 bftpd_log 844 ("Exiting, becasue we have no way to authorize clients.\n"); 845 exit (0); 846 } 847 } 848#endif 849 850 control_timeout = strtoul (config_getoption ("CONTROL_TIMEOUT"), NULL, 0); 851 if (!control_timeout) 852 control_timeout = CONTROL_TIMEOUT; 853 data_timeout = strtoul (config_getoption ("DATA_TIMEOUT"), NULL, 0); 854 if (!data_timeout) 855 data_timeout = DATA_TIMEOUT; 856 xfer_bufsize = strtoul (config_getoption ("XFER_BUFSIZE"), NULL, 0); 857 if (!xfer_bufsize) 858 xfer_bufsize = XFER_BUFSIZE; 859 860 /* get scripts to run pre and post write */ 861 pre_write_script = config_getoption ("PRE_WRITE_SCRIPT"); 862 if (!pre_write_script[0]) 863 pre_write_script = NULL; 864 post_write_script = config_getoption ("POST_WRITE_SCRIPT"); 865 if (!post_write_script[0]) 866 post_write_script = NULL; 867 868 869 my_length = sizeof (remotename); 870 if (getpeername 871 (fileno (stderr), (struct sockaddr *) &remotename, &my_length)) 872 { 873 control_printf (SL_FAILURE, 874 "421-Could not get peer IP address.\r\n421 %s.", 875 strerror (errno)); 876 return 0; 877 } 878 i = 1; 879 setsockopt (fileno (stdin), SOL_SOCKET, SO_OOBINLINE, (void *) &i, 880 sizeof (i)); 881 setsockopt (fileno (stdin), SOL_SOCKET, SO_KEEPALIVE, (void *) &i, 882 sizeof (i)); 883 /* If option is set, determine the client FQDN */ 884 if (!strcasecmp ((char *) config_getoption ("RESOLVE_CLIENT_IP"), "yes")) 885 { 886 if ((he = 887 gethostbyaddr ((char *) &remotename.sin_addr, 888 sizeof (struct in_addr), AF_INET))) 889 remotehostname = strdup (he->h_name); 890 else 891 remotehostname = strdup (inet_ntoa (remotename.sin_addr)); 892 } 893 else 894 remotehostname = strdup (inet_ntoa (remotename.sin_addr)); 895 bftpd_log ("Incoming connection from %s.\n", remotehostname); 896 897 /* Foxconn, added by MJ., 2010.03.25, for count the totoal connections 898 * of accessing USB dir. 899 */ 900 /*if(con_st != NULL) 901 { 902 binary_semaphore_wait(con_st->sem_id); 903 if(con_st->num >= MAX_CON_NUM){ 904 ++(con_st->num); 905 printf("The Connections are over 15.\n"); 906 binary_semaphore_post(con_st->sem_id); 907 goto exit; 908 } 909 910 ++(con_st->num); 911 binary_semaphore_post(con_st->sem_id); 912#ifdef CON_DEBUG 913 printf("->total con num: %d, by bftpd.\n", con_st->num); 914#endif 915 }*/ 916 /* Foxconn, ended by MJ., 2010.03.25 */ 917 918 919 bftpd_statuslog (1, 0, "connect %s", remotehostname); 920 my_length = sizeof (name); 921 getsockname (fileno (stdin), (struct sockaddr *) &name, &my_length); 922 print_file (220, config_getoption ("MOTD_GLOBAL")); 923 /* Parse hello message */ 924 strcpy (str, (char *) config_getoption ("HELLO_STRING")); 925 replace (str, "%v", VERSION); 926 if (strstr (str, "%h")) 927 { 928 if ((he = 929 gethostbyaddr ((char *) &name.sin_addr, sizeof (struct in_addr), 930 AF_INET))) 931 replace (str, "%h", he->h_name); 932 else 933 replace (str, "%h", (char *) inet_ntoa (name.sin_addr)); 934 } 935 replace (str, "%i", (char *) inet_ntoa (name.sin_addr)); 936 937 /* Foxconn modified start pling 06/10/2009*/ 938 /* If all shared folders are 'All - no password', 939 * then no need to login for "FTP", 940 * by auto-login as user 'guest'. 941 */ 942 FILE* fp = NULL; 943 fp = fopen("/tmp/all_no_password","r"); 944 if (fp != NULL) 945 { 946 fclose(fp); 947 command_user("no_pass"); 948 all_no_password = 1; 949 } 950 else 951 control_printf (SL_SUCCESS, "220 %s", str); 952 /* Foxconn modified end pling 06/10/2009*/ 953 954 /* We might not get any data, so let's set an alarm before the 955 first read. -- Jesse <slicer69@hotmail.com> */ 956 alarm (control_timeout); 957 958 /* Read lines from client and execute appropriate commands */ 959 while (fgets (str, sizeof (str), stdin)) 960 { 961 alarm (control_timeout); 962 str[strlen (str) - 2] = 0; 963 bftpd_statuslog (2, 0, "%s", str); 964#ifdef DEBUG 965 bftpd_log ("Processing command: %s\n", str); 966#endif 967 parsecmd (str); 968 } 969 970 if (remotehostname) 971 free (remotehostname); 972 973 //if(con_st != NULL) 974 //{ 975 // binary_semaphore_wait(con_st->sem_id); 976 // --(con_st->num); 977 // binary_semaphore_post(con_st->sem_id); 978exit: 979 // printf("->total con num: %d, by bftpd\n", con_st->num); 980 //} 981 /* Foxconn, ended by MJ., 2010.03.25 */ 982 983 return 0; 984} 985