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