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.\n");
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
233
234
235/*
236This function causes the program to
237re-read parts of the config file.
238
239-- Jesse
240*/
241void handler_sighup (int sig)
242{
243    bftpd_log("%s.\n", __FUNCTION__);
244    /* Foxconn, added by MJ., 2010.04.29, for connections counting. */
245    /*if(con_st != NULL)
246    {
247        binary_semaphore_wait(con_st->sem_id);
248        --(con_st->num);
249        binary_semaphore_post(con_st->sem_id);
250#ifdef CON_DEBUG
251        printf("->total con num: %d, by bftpd\n",
252                con_st->num);
253#endif
254    }*/
255    /* Foxconn, ended by MJ., 2010.04.29. */
256    bftpd_log ("Caught HUP signal. Re-reading config file.\n");
257    Reread_Config_File ();
258    signal (sig, handler_sighup);
259}
260
261
262
263
264void handler_sigchld (int sig)
265{
266    pid_t pid;
267    int i;
268    struct bftpd_childpid *childpid;
269
270    bftpd_log("%s\n", __FUNCTION__);
271
272    /* Foxconn, added by MJ., 2010.03.30, for connections counting. */
273#ifdef MAX_USB_ACCESS_OLD
274    if(con_st != NULL)
275    {
276        FILE *pfp;
277        int bftpd_pid;
278        int wan_ftp = 0;
279        if ((pfp = fopen ("/var/run/bftpd_wan.pid", "r")))
280        {
281            char tmp[32];
282            fgets(tmp, 80, pfp);
283            bftpd_pid = atoi(tmp);
284            if((getpid() == bftpd_pid))
285                wan_ftp = 1;
286            fclose(pfp);
287        }
288        binary_semaphore_wait(con_st->sem_id);
289	if(con_st->num > 0)
290	{
291            --(con_st->num);
292            if(wan_ftp)
293	    	--(con_st->wan_ftp_num);
294            else
295		--(con_st->ftp_num);
296	}
297        binary_semaphore_post(con_st->sem_id);
298#ifdef CON_DEBUG
299        printf("->total con num: %d, by bftpd\n", con_st->num);
300#endif
301    }
302#endif // End of MAX_USB_ACCESS
303    /* Foxconn, ended by MJ., 2010.03.30. */
304
305
306    /* Get the child's return code so that the zombie dies */
307    pid = wait (NULL);
308    for (i = 0; i < bftpd_list_count (child_list); i++)
309    {
310        childpid = bftpd_list_get (child_list, i);
311        if (childpid->pid == pid)
312        {
313            close (childpid->sock);
314            bftpd_list_del (&child_list, i);
315            free (childpid);
316            /* make sure the child is removed from the log */
317            bftpdutmp_remove_pid (pid);
318#ifdef MAX_USB_ACCESS
319	    dec_conn_num();
320#endif
321        }
322    }
323}
324
325void handler_sigterm (int signum)
326{
327    bftpd_log ("%s.\n", __FUNCTION__);
328    /* Foxconn, added by MJ., 2010.04.29, for connections counting. */
329/*    if(con_st != NULL)
330    {
331	binary_semaphore_wait(con_st->sem_id);
332	//if(con_st->ftp_num != 0)
333        (con_st->num) = (con_st->num) -100;
334        binary_semaphore_post(con_st->sem_id);
335#ifdef CON_DEBUG
336        printf("->total con num: %d, by bftpd\n",
337               con_st->num);
338#endif
339    }*/
340    /* Foxconn, ended by MJ., 2010.04.29. */
341
342
343    bftpdutmp_end ();
344    exit (0);                   /* Force normal termination so that end_child() is called */
345}
346
347void handler_sigalrm (int signum)
348{
349    printf("%s:\n", __FUNCTION__);
350    /* Log user out. -- Jesse <slicer69@hotmail.com> */
351    bftpdutmp_end ();
352
353    /* Foxconn, added by MJ., 2010.03.30, for connections counting. */
354/*    if(con_st != NULL)
355    {
356        binary_semaphore_wait(con_st->sem_id);
357        --(con_st->num);
358        binary_semaphore_post(con_st->sem_id);
359#ifdef CON_DEBUG
360        printf("->total con num: %d, by bftpd\n", con_st->num);
361#endif
362    }*/
363    /* Foxconn, ended by MJ., 2010.03.30. */
364
365    if (alarm_type)
366    {
367        close (alarm_type);
368
369        bftpd_log
370            ("Kicked from the server due to data connection timeout.\n");
371        control_printf (SL_FAILURE,
372                        "421 Kicked from the server due to data connection timeout.");
373        exit (0);
374    }
375    else
376    {
377        bftpd_log
378            ("Kicked from the server due to control connection timeout.\n");
379        control_printf (SL_FAILURE,
380                        "421 Kicked from the server due to control connection timeout.");
381        exit (0);
382    }
383}
384
385void init_everything ()
386{
387    if (!daemonmode)
388    {
389        config_init ();
390        hidegroups_init ();
391    }
392    log_init ();
393    bftpdutmp_init ();
394    login_init ();
395}
396
397#ifdef MAX_USB_ACCESS
398int dec_conn_num()
399{
400    if(con_st != NULL)
401    {
402        FILE *pfp;
403        int bftpd_pid;
404        int wan_ftp = 0;
405        if ((pfp = fopen ("/var/run/bftpd_wan.pid", "r")))
406	{
407	    char tmp[32];
408	    fgets(tmp, 80, pfp);
409	    bftpd_pid = atoi(tmp);
410	    if((getpid() == bftpd_pid))
411	          wan_ftp = 1;
412	    fclose(pfp);
413        }
414        binary_semaphore_wait(con_st->sem_id);
415        if(con_st->num > 0)
416	{
417	     --(con_st->num);
418	     if(wan_ftp)
419	         --(con_st->wan_ftp_num);
420	     else
421	         --(con_st->ftp_num);
422	}
423        binary_semaphore_post(con_st->sem_id);
424//#ifdef CON_DEBUG
425        //cprintf("->total con num: %d, by bftpd\n", con_st->num);
426//#endif
427    }
428    /* Foxconn, ended by MJ., 2010.03.30. */
429}
430
431int inc_conn_num ()
432{
433    if(con_st != NULL)
434    {
435	FILE *pfp;
436	int bftpd_pid;
437	int wan_ftp = 0;
438
439	if ((pfp = fopen ("/var/run/bftpd_wan.pid", "r")))
440	{
441	    char tmp[32];
442	    fgets(tmp, 80, pfp);
443	    bftpd_pid = atoi(tmp);
444	    if((getppid() == bftpd_pid))
445	        wan_ftp = 1;
446	    fclose(pfp);
447	}
448        binary_semaphore_wait(con_st->sem_id);
449        if(con_st->num >= MAX_CON_NUM){
450            ++(con_st->num);
451	    if(wan_ftp)
452		++(con_st->wan_ftp_num);
453	    else
454	        ++(con_st->ftp_num);
455            printf("The Connections are over 15.\n");
456            binary_semaphore_post(con_st->sem_id);
457            return 0;
458        }
459
460        ++(con_st->num);
461        if(wan_ftp)
462	    ++(con_st->wan_ftp_num);
463	else
464	    ++(con_st->ftp_num);
465        binary_semaphore_post(con_st->sem_id);
466//#ifdef CON_DEBUG
467        //cprintf("->total con num: %d, by bftpd.\n", con_st->num);
468//#endif
469        return 1;
470    }
471    return 0;
472}
473#endif
474
475int main (int argc, char **argv)
476{
477    char str[MAXCMD + 1];
478    static struct hostent *he;
479    int i = 1, port;
480    int retval;
481    int over_limit = 0;
482    socklen_t my_length;
483    FILE *pid_fp;/* Foxconn add, Jasmine Yang, 09/13/2007 */
484    extern int cur_conn;
485
486    my_argv_list = argv;
487    signal (SIGHUP, handler_sighup);
488
489    /* Foxconn, added by MJ., 2010.03.25, for count the totoal connections
490     * of accessing USB dir.
491     */
492#ifdef MAX_USB_ACCESS
493    FILE *shmid_fp = fopen("/tmp/shm_id", "r");
494    if(shmid_fp != NULL)
495    {
496        fscanf(shmid_fp, "%d", &segment_id);
497        printf("bftpd: segment_id:%d\n", segment_id);
498        fclose(shmid_fp);
499    }
500    else{
501        printf("/tmp/shm_id open failed.\n");
502        segment_id = -1;
503        //exit(1);
504    }
505    /* attach the shared memory segment, at a different address. */
506    if(segment_id != -1){
507        con_st = (CON_STATISTIC*) shmat (segment_id, (void*) 0x5000000, 0);
508        printf ("shared memory reattached at address %p\n", con_st);
509    }    else {
510        con_st = NULL;
511	printf ("fail to get shared memory reattached at address \n");
512    }
513#endif // End of MAX_USB_ACCESS
514    /*Foxconn, ended by MJ., 2010.03.25*/
515
516
517
518
519    while (((retval = getopt (argc, argv, "c:hdDin"))) > -1)
520    {
521        switch (retval)
522        {
523        case 'h':
524            printf ("Usage: %s [-h] [-i|-d|-D] [-c <filename>|-n]\n"
525                    "-h print this help\n" "-i (default) run from inetd\n"
526                    "-d daemon mode: fork() and run in TCP listen mode\n"
527                    "-D run in TCP listen mode, but don't pre-fork()\n"
528                    "-c read the config file named \"filename\" instead of "
529                    PATH_BFTPD_CONF "\n" "-n no config file, use defaults\n",
530                    argv[0]);
531            return 0;
532        case 'i':
533            daemonmode = 0;
534            break;
535        case 'd':
536            daemonmode = 1;
537            break;
538        case 'D':
539            daemonmode = 2;
540            break;
541        case 'c':
542            configpath = strdup (optarg);
543            break;
544        case 'n':
545            configpath = NULL;
546            break;
547        }
548    }
549    if (daemonmode)
550    {
551        struct sockaddr_in myaddr, new;
552
553        if (daemonmode == 1)
554        {
555            if (fork ())
556                exit (0);       /* Exit from parent process */
557            setsid ();
558            if (fork ())
559                return 0;
560/* Foxconn add start, Jasmine Yang, 09/13/2007 */
561            if (!(pid_fp = fopen ("/var/run/bftpd.pid", "w")))
562            {
563                perror ("/var/run/bftpd.pid");
564                return 0;
565            }
566            fprintf (pid_fp, "%d", getpid ());
567            fclose (pid_fp);
568/* Foxconn add end, Jasmine Yang, 09/13/2007 */
569        }
570        signal (SIGCHLD, handler_sigchld);
571
572//#ifndef QUICK_FIX_ISSUES //@ftpRW : we need this
573//FIXME
574        config_init ();
575//#endif
576        chdir ("/");
577        hidegroups_init ();
578        listensocket = socket (AF_INET, SOCK_STREAM, 0);
579#ifdef SO_REUSEADDR
580        setsockopt (listensocket, SOL_SOCKET, SO_REUSEADDR, (void *) &i,
581                    sizeof (i));
582#endif
583#ifdef SO_REUSEPORT
584        setsockopt (listensocket, SOL_SOCKET, SO_REUSEPORT, (void *) &i,
585                    sizeof (i));
586#endif
587        memset ((void *) &myaddr, 0, sizeof (myaddr));
588        if (!((port = strtoul (config_getoption ("PORT"), NULL, 10))))
589            port = DEFAULT_PORT;
590        myaddr.sin_port = htons (port);
591        if (!strcasecmp (config_getoption ("BIND_TO_ADDR"), "any")
592            || !config_getoption ("BIND_TO_ADDR")[0])
593            myaddr.sin_addr.s_addr = INADDR_ANY;
594        else{
595            char file_path[256];
596            FILE *pfp;
597
598            myaddr.sin_addr.s_addr =
599                inet_addr (config_getoption ("BIND_TO_ADDR"));
600
601            printf("write pid:%d tp /var/run/bftpd_wan.pid.\n", getpid());
602
603            if (!(pfp = fopen ("/var/run/bftpd_wan.pid", "w")))
604            {
605                perror ("/var/run/bftpd_wan.pid");
606                return 0;
607            }
608            fprintf (pfp, "%d", getpid ());
609            fclose (pfp);
610        }
611        if (bind (listensocket, (struct sockaddr *) &myaddr, sizeof (myaddr))
612            < 0)
613        {
614            fprintf (stderr, "Bind failed: %s\n", strerror (errno));
615            exit (1);
616        }
617        else
618            printf("bftpd: socket bound in %s:%d\n", inet_ntoa(myaddr.sin_addr), port);
619
620        if (listen (listensocket, 1))
621        {
622            fprintf (stderr, "Listen failed: %s\n", strerror (errno));
623            exit (1);
624        }
625
626        for (i = 0; i < 3; i++)
627        {
628            close (i);          /* Remove fd pointing to the console */
629            open ("/dev/null", O_RDWR); /* Create fd pointing nowhere */
630        }
631
632        my_length = sizeof (new);
633        while ((sock =
634                accept (listensocket, (struct sockaddr *) &new, &my_length)))
635        {
636            pid_t pid;
637
638	    over_limit = 0;
639
640            /* Foxconn added start by Jenny Zhao, 06/13/2011 @USB log */
641            strcpy(client_ip, inet_ntoa(new.sin_addr));
642            g_isLanIp = isLanSubnet(client_ip);
643            /* Foxconn added end by Jenny Zhao, 06/13/2011 */
644
645#ifdef MAX_USB_ACCESS
646	    /* Foxconn, CSWang, limit 15 connection */
647            /* printf("cur conn:%d %d\n", cur_conn, bftpd_list_count( &child_list) ); */
648            if ( cur_conn > MAX_CON_NUM ) {
649                 close(sock);
650                 continue;
651            }
652
653            if(con_st != NULL)
654            {
655                 printf("curconn:%d\n", con_st->num);
656                 if ( con_st->num >= MAX_CON_NUM ) {
657		 //if ( con_st->num >= 3 ) {
658	             close(sock);
659                     /* printf("over 15 connection"); */
660                     //sleep(1);
661		     over_limit = 1;
662                 }
663
664		 if( over_limit ) {
665                    over_limit = 0;
666  		    continue;
667                 }
668            }
669#endif
670            /* If accept() becomes interrupted by SIGCHLD, it will return -1.
671             * So in order not to create a child process when that happens,
672             * we have to check if accept() returned an error.
673             */
674            if (sock > 0)
675            {
676                pid = fork ();
677                if (!pid)
678                {               /* child */
679                    close (0);
680                    close (1);
681                    close (2);
682                    isparent = 0;
683                    dup2 (sock, fileno (stdin));
684                    dup2 (sock, fileno (stderr));
685                    break;
686                }
687                else
688                {               /* parent */
689                    struct bftpd_childpid *tmp_pid;
690
691		    tmp_pid = malloc (sizeof (struct bftpd_childpid));
692                    tmp_pid->pid = pid;
693                    tmp_pid->sock = sock;
694                    bftpd_list_add (&child_list, tmp_pid);
695#ifdef MAX_USB_ACCESS
696		    inc_conn_num();
697#endif
698	         }
699             }
700        }
701    }
702
703    /* Child only. From here on... */
704
705    //Foxconn modify, Jasmine Yang, 09/12/2007
706    //devnull = fopen ("/dev/null", "w");
707    devnull = fopen ("/dev/console", "w");
708    global_argc = argc;
709    global_argv = argv;
710    init_everything ();
711
712    atexit (end_child);
713
714    /* Foxconn, added by MJ., 2010.03.25, for count the totoal connections
715     * of accessing USB dir.
716     */
717#ifdef MAX_USB_ACCESS_OLD
718    if(con_st != NULL)
719    {
720	FILE *pfp;
721	int bftpd_pid;
722	int wan_ftp = 0;
723
724	if ((pfp = fopen ("/var/run/bftpd_wan.pid", "r")))
725	{
726	    char tmp[32];
727	    fgets(tmp, 80, pfp);
728	    bftpd_pid = atoi(tmp);
729	    if((getppid() == bftpd_pid))
730	        wan_ftp = 1;
731	    fclose(pfp);
732	}
733        binary_semaphore_wait(con_st->sem_id);
734        if(con_st->num >= MAX_CON_NUM){
735            ++(con_st->num);
736	    if(wan_ftp)
737		++(con_st->wan_ftp_num);
738	    else
739	        ++(con_st->ftp_num);
740            printf("The Connections are over 15.\n");
741            binary_semaphore_post(con_st->sem_id);
742            goto exit;
743        }
744
745        ++(con_st->num);
746        if(wan_ftp)
747	    ++(con_st->wan_ftp_num);
748	else
749	    ++(con_st->ftp_num);
750        binary_semaphore_post(con_st->sem_id);
751#ifdef CON_DEBUG
752        printf("->total con num: %d, by bftpd.\n", con_st->num);
753#endif
754    }
755#endif // End of MAX_USB_ACCESS
756    /* Foxconn, ended by MJ., 2010.03.25 */
757
758    //atexit (end_child);
759    signal (SIGTERM, handler_sigterm);
760    signal (SIGALRM, handler_sigalrm);
761
762
763    /* If we do not have getpwnam() for some reason, then
764       we must use FILE_AUTH or exit. */
765#ifdef NO_GETPWNAM
766    {
767        char *file_auth_option;
768
769        file_auth_option = config_getoption ("FILE_AUTH");
770        if (!file_auth_option[0])
771        {
772            bftpd_log
773                ("Exiting, becasue we have no way to authorize clients.\n");
774            exit (0);
775        }
776    }
777#endif
778
779    control_timeout = strtoul (config_getoption ("CONTROL_TIMEOUT"), NULL, 0);
780    if (!control_timeout)
781        control_timeout = CONTROL_TIMEOUT;
782    data_timeout = strtoul (config_getoption ("DATA_TIMEOUT"), NULL, 0);
783    if (!data_timeout)
784        data_timeout = DATA_TIMEOUT;
785    xfer_bufsize = strtoul (config_getoption ("XFER_BUFSIZE"), NULL, 0);
786    if (!xfer_bufsize)
787        xfer_bufsize = XFER_BUFSIZE;
788
789    /* get scripts to run pre and post write */
790    pre_write_script = config_getoption ("PRE_WRITE_SCRIPT");
791    if (!pre_write_script[0])
792        pre_write_script = NULL;
793    post_write_script = config_getoption ("POST_WRITE_SCRIPT");
794    if (!post_write_script[0])
795        post_write_script = NULL;
796
797
798    my_length = sizeof (remotename);
799    if (getpeername
800        (fileno (stderr), (struct sockaddr *) &remotename, &my_length))
801    {
802        control_printf (SL_FAILURE,
803                        "421-Could not get peer IP address.\r\n421 %s.",
804                        strerror (errno));
805        return 0;
806    }
807    i = 1;
808    setsockopt (fileno (stdin), SOL_SOCKET, SO_OOBINLINE, (void *) &i,
809                sizeof (i));
810    setsockopt (fileno (stdin), SOL_SOCKET, SO_KEEPALIVE, (void *) &i,
811                sizeof (i));
812    /* If option is set, determine the client FQDN */
813    if (!strcasecmp ((char *) config_getoption ("RESOLVE_CLIENT_IP"), "yes"))
814    {
815        if ((he =
816             gethostbyaddr ((char *) &remotename.sin_addr,
817                            sizeof (struct in_addr), AF_INET)))
818            remotehostname = strdup (he->h_name);
819        else
820            remotehostname = strdup (inet_ntoa (remotename.sin_addr));
821    }
822    else
823        remotehostname = strdup (inet_ntoa (remotename.sin_addr));
824    bftpd_log ("Incoming connection from %s.\n", remotehostname);
825
826    /* Foxconn, added by MJ., 2010.03.25, for count the totoal connections
827     * of accessing USB dir.
828     */
829    /*if(con_st != NULL)
830    {
831        binary_semaphore_wait(con_st->sem_id);
832        if(con_st->num >= MAX_CON_NUM){
833	    ++(con_st->num);
834            printf("The Connections are over 15.\n");
835            binary_semaphore_post(con_st->sem_id);
836            goto exit;
837        }
838
839        ++(con_st->num);
840        binary_semaphore_post(con_st->sem_id);
841#ifdef CON_DEBUG
842        printf("->total con num: %d, by bftpd.\n", con_st->num);
843#endif
844    }*/
845    /* Foxconn, ended by MJ., 2010.03.25 */
846
847
848    bftpd_statuslog (1, 0, "connect %s", remotehostname);
849    my_length = sizeof (name);
850    getsockname (fileno (stdin), (struct sockaddr *) &name, &my_length);
851    print_file (220, config_getoption ("MOTD_GLOBAL"));
852    /* Parse hello message */
853    strcpy (str, (char *) config_getoption ("HELLO_STRING"));
854    replace (str, "%v", VERSION);
855    if (strstr (str, "%h"))
856    {
857        if ((he =
858             gethostbyaddr ((char *) &name.sin_addr, sizeof (struct in_addr),
859                            AF_INET)))
860            replace (str, "%h", he->h_name);
861        else
862            replace (str, "%h", (char *) inet_ntoa (name.sin_addr));
863    }
864    replace (str, "%i", (char *) inet_ntoa (name.sin_addr));
865
866	/* Foxconn modified start pling 06/10/2009*/
867	/* If all shared folders are 'All - no password',
868	 * then no need to login for "FTP",
869	 * by auto-login as user 'guest'.
870	 */
871	FILE* fp = NULL;
872	fp = fopen("/tmp/all_no_password","r");
873	if (fp != NULL)
874	{
875		fclose(fp);
876		command_user("guest");
877		all_no_password = 1;
878	}
879	else
880		control_printf (SL_SUCCESS, "220 %s", str);
881	/* Foxconn modified end pling 06/10/2009*/
882
883    /* We might not get any data, so let's set an alarm before the
884       first read. -- Jesse <slicer69@hotmail.com> */
885    alarm (control_timeout);
886
887    /* Read lines from client and execute appropriate commands */
888    while (fgets (str, sizeof (str), stdin))
889    {
890        alarm (control_timeout);
891        str[strlen (str) - 2] = 0;
892        bftpd_statuslog (2, 0, "%s", str);
893#ifdef DEBUG
894        bftpd_log ("Processing command: %s\n", str);
895#endif
896        parsecmd (str);
897    }
898
899    if (remotehostname)
900        free (remotehostname);
901
902    //if(con_st != NULL)
903    //{
904    //    binary_semaphore_wait(con_st->sem_id);
905    //    --(con_st->num);
906    //    binary_semaphore_post(con_st->sem_id);
907exit:
908    //    printf("->total con num: %d, by bftpd\n", con_st->num);
909    //}
910    /* Foxconn, ended by MJ., 2010.03.25 */
911
912    return 0;
913}
914