1#include <stdio.h>
2#include <string.h>
3#include <unistd.h>
4#include <signal.h>
5#include <sys/types.h>
6#include <sys/time.h>
7#include <sys/wait.h>
8#include <sys/socket.h>
9#include <netinet/in.h>
10#include <arpa/inet.h>
11#include <errno.h>
12#include <linux/lp.h>
13#include <fcntl.h>
14#include "wlancom.h"
15#include "lp_asus.h"
16#include "syslog.h"
17
18#include <semaphore_mfp.h>
19#include <bcmnvram.h>
20#include <netinet/tcp.h>
21
22/*Lisa*/
23#include	<stdlib.h>
24#include	<getopt.h>
25#include	<ctype.h>
26#include	<fcntl.h>
27#include	<netdb.h>
28#include	<syslog.h>
29#include	<sys/resource.h>
30#include	<sys/stat.h>
31#include 	<sys/ioctl.h>
32#define		BASEPORT	9100
33#ifdef 		DEBUG
34#define		PRINT(...)
35#else
36#define		PRINT	printf
37#endif
38#define 	Raw_Printing_with_ASUS
39#define 	LOGOPTS		(LOG_PERROR|LOG_PID|LOG_LPR|LOG_ERR)
40
41/* 2004/09/10, added by Joey
42 * The printer server desing
43 * Remote Port/LPR/Raw
44 * 1. fork() for one printing job at the same time.
45 * 2. the nack is processed in parent process.
46 * 3. busyflag is used globally in parent proces
47 * 4. lptstatus.busy is used between parent and child
48 */
49
50//JY
51#include "lp.h"
52#define MAX(a, b) ((a) > (b) ? (a) : (b))//JY1112
53
54
55extern int          errno;
56
57
58#ifdef LPR_with_ASUS//JY1112
59#define PNT_SVR_PORT_ASUS    3838
60#endif
61#define PNT_SVR_PORT_LPR 515
62#define PRINT printf
63
64#define UCHAR unsigned char
65
66#define STATUS_FILE "/var/state/parport/svr_status"
67
68
69int processReq(int sockfd); //Process the request from the client side
70int closesocket(int sockfd);
71void sig_child(int sig);    //signal handler to the dead of child process
72void sig_cleanup(int sig);
73void sig_remove(int sig);//JY1110
74//void checkstatus_usb_par();//JY1110
75int waitsock(int sockfd , int sec , int usec);  //wait to socket until timeout
76void reset_printer(int sec);
77int check_par_usb_prn();//JY: 20031104 change to int from void
78DWORD RECV(int sockfd , PBYTE pRcvbuf , DWORD dwlen , DWORD timeout);
79
80int  fdPRN=0; //File descriptor of the printer port
81char g_useUsb = FALSE;
82char busy = FALSE; //Add by Lisa
83void check_prn_status(char *status_prn, char *cliadd_prn); //Added by Jiahao
84void processReq_Raw(int fd); //Added by Jiahao
85
86/*
87 * logmessage
88 *
89 */
90void logmessage(char *logheader, char *fmt, ...)
91{
92  va_list args;
93  char buf[512];
94
95  va_start(args, fmt);
96
97  vsnprintf(buf, sizeof(buf), fmt, args);
98  openlog(logheader, 0, 0);
99  syslog(0, buf);
100  closelog();
101  va_end(args);
102}
103
104
105
106void main()
107{
108    int                 sockfd , clisockfd;
109    unsigned int        clilen;
110    int                 childpid;
111    struct sockaddr_in  serv_addr,cli_addr;
112    int err_select;//JY1113
113
114#ifdef LPR_with_ASUS//JY1112
115    int 		LPRflag = 0;
116    fd_set		rfds, afds;
117    int			nfds;
118    int			sockfd_ASUS;
119    unsigned int        clilen_ASUS;
120    int                 childpid_ASUS;
121    struct sockaddr_in  serv_addr_ASUS,cli_addr_ASUS;
122#endif
123#ifdef Raw_Printing_with_ASUS  //Lisa
124	int		netfd, fd, clientlen, one = 1;
125	struct sockaddr_in	netaddr, client;
126#endif
127
128    //Initial the server the not busy
129    lptstatus.busy = FALSE;
130
131    //Setup the signal handler
132    signal(SIGCLD, sig_child);
133    signal(SIGINT, sig_cleanup);
134    signal(SIGQUIT, sig_cleanup);
135    signal(SIGKILL, sig_cleanup);
136    signal(SIGUSR2, sig_remove);//JY1110
137
138    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0 )
139    {
140        //perror("can't open stream socket:");
141        exit(0);
142    }
143
144    bzero((char *)&serv_addr , sizeof(serv_addr));
145    serv_addr.sin_family        = AF_INET;
146    serv_addr.sin_addr.s_addr   = htonl(INADDR_ANY);
147    serv_addr.sin_port          = htons(PNT_SVR_PORT_LPR);
148
149
150    if(bind(sockfd,(struct sockaddr *)&serv_addr , sizeof(serv_addr)) < 0 )
151    {
152        //perror("can't bind:");
153        exit(0);
154    }
155    /*JY1111*/
156    int windowsize=2920;
157    setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&windowsize, sizeof(windowsize));
158    int no_delay=1;
159    setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &no_delay, sizeof(no_delay));	// by Jiahao. 20080808.
160
161#if 1
162    int currentpid=getpid();
163    FILE *pidfileread;
164
165    if((pidfileread=fopen("/var/run/lpdparent.pid", "r")) == NULL)
166    {
167		pidfileread=fopen("/var/run/lpdparent.pid", "w");
168		fprintf(pidfileread, "%d", currentpid);
169		fclose(pidfileread);
170    }
171    else{
172		//printf("another lpd daemon exists!!\n");
173		fclose(pidfileread);
174               	exit(0);
175    }
176#endif
177    listen(sockfd , 15);
178
179#ifdef Raw_Printing_with_ASUS //Lisa
180	if ((netfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
181	{
182//		syslog(LOGOPTS, "socket: %m\n");
183		exit(1);
184	}
185	if (setsockopt(netfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0)
186	{
187//		syslog(LOGOPTS, "setsocketopt: %m\n");
188		exit(1);
189	}
190	netaddr.sin_port = htons(BASEPORT);
191	netaddr.sin_addr.s_addr = htonl(INADDR_ANY);
192	memset(netaddr.sin_zero, 0, sizeof(netaddr.sin_zero));
193	if (bind(netfd, (struct sockaddr*) &netaddr, sizeof(netaddr)) < 0)
194	{
195		//syslog(LOGOPTS, "bind: %m\n");
196		exit(1);
197	}
198	if (listen(netfd, 5) < 0)
199	{
200		//syslog(LOGOPTS, "listen: %m\n");
201		exit(1);
202	}
203	//clientlen = sizeof(client);
204	//memset(&client, 0, sizeof(client));
205#endif
206
207#ifdef LPR_with_ASUS//JY1112
208	if((sockfd_ASUS = socket(AF_INET,SOCK_STREAM,0)) < 0 )
209	{
210	        //perror("can't open stream socket:");
211	        exit(0);
212	}
213    	bzero((char *)&serv_addr_ASUS , sizeof(serv_addr_ASUS));
214    	serv_addr_ASUS.sin_family        = AF_INET;
215    	serv_addr_ASUS.sin_addr.s_addr   = htonl(INADDR_ANY);
216    	serv_addr_ASUS.sin_port          = htons(PNT_SVR_PORT_ASUS);
217
218    	if(bind(sockfd_ASUS,(struct sockaddr *)&serv_addr_ASUS , sizeof(serv_addr_ASUS)) < 0 )
219    	{
220        	//perror("can't bind:");
221		exit(0);
222   	}
223
224    	setsockopt(sockfd_ASUS, SOL_SOCKET, SO_RCVBUF, (char *)&windowsize, sizeof(windowsize));
225
226    	listen(sockfd_ASUS , 15);
227
228    	/*set the fds*/
229    	nfds=MAX(sockfd, sockfd_ASUS);
230    	FD_ZERO(&afds);
231#endif
232
233    while(TRUE)
234    {
235	//if (busy) syslog(LOG_NOTICE, "busying %d %d\n", lptstatus.busy, busy);
236
237	semaphore_wait();						// by Jiahao for U2EC. 20080808.
238	if (lptstatus.busy==FALSE && nvram_invmatch("MFP_busy", "2"))
239	{
240		busy=FALSE;
241		nvram_set("MFP_busy", "0");
242
243		nvram_set("u2ec_busyip", "");
244	}
245	semaphore_post();
246
247#ifdef Raw_Printing_with_ASUS //Lisa
248	FD_SET(netfd, &afds);
249#endif
250#ifdef LPR_with_ASUS//JY1112
251	FD_SET(sockfd, &afds);
252	FD_SET(sockfd_ASUS, &afds);
253	memcpy(&rfds, &afds, sizeof(rfds));
254
255	if((err_select=select(nfds+1, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0 )) < 0)
256	{
257//JY1120	printf("select error on sockfd: error=%d\n", errno);
258		/**/
259//		printf("sockfd_FD_ISSET=%d\n", FD_ISSET(sockfd, &rfds));
260//JY1120		printf("sockfd_ASUS FD_ISSET=%d\n", FD_ISSET(sockfd_ASUS, &rfds));
261		/**/
262//		if(errno != 4)//JY1113: delete
263		//syslog(LOG_NOTICE, "select error %d\n", err_select);
264		continue;
265	}
266#endif
267        clilen = sizeof(cli_addr);
268
269	if(FD_ISSET(sockfd_ASUS, &rfds))
270	{
271		LPRflag = 0;
272		clisockfd   = accept(sockfd_ASUS,(struct sockaddr *)&cli_addr, &clilen);
273	}
274#ifdef LPR_with_ASUS//JY1112
275	else if(FD_ISSET(sockfd, &rfds))
276	{
277		LPRflag = 1;
278		clisockfd   = accept(sockfd,(struct sockaddr *)&cli_addr, &clilen);
279	}
280#endif
281#ifdef Raw_Printing_with_ASUS //Lisa
282//	else if(FD_ISSET(netfd, &rfds) && busy==FALSE)
283	else if(FD_ISSET(netfd, &rfds))
284	{
285		semaphore_wait();			// by Jiahao for U2EC. 20080808.
286		if (nvram_match("MFP_busy", "0"))
287		{
288			semaphore_post();
289			LPRflag = 2;
290			clisockfd = accept(netfd, (struct sockaddr*) &cli_addr, &clilen);
291		}
292		else
293		{
294			semaphore_post();
295			sleep(2);
296			continue;
297		}
298	}
299#endif
300	else
301        {
302		//syslog(LOG_NOTICE, "No select\n");
303		sleep(2);
304		continue;
305	}
306
307	strcpy(clientaddr , inet_ntoa(cli_addr.sin_addr));
308
309	if(clisockfd < 0)
310        {
311	     //syslog(LOG_NOTICE, "LPD error: No clisockfd %d\n", LPRflag);
312             continue;
313        }
314
315	semaphore_wait();
316//	if (busy!=FALSE)	/* 2004/09/10 by Joey, process nack in parent for LPR and Remote Prot */
317	if (nvram_invmatch("MFP_busy", "0"))		// by Jiahao for U2EC. 20080808.
318	{
319		semaphore_post();
320		//syslog(LOG_NOTICE, "Printing others 1 %d %d\n", LPRflag, clisockfd);
321		if (LPRflag==0) processReq(clisockfd);
322		else if (LPRflag==1) processReq_LPR(clisockfd, 0);
323		//syslog(LOG_NOTICE, "Printing others %d %d\n", LPRflag, clisockfd);
324		close(clisockfd);
325		// For Raw printing, don't resonse to client while busy
326		sleep(5);
327		continue;
328	}
329
330	nvram_set("MFP_busy", "1");
331
332	if (nvram_match("lan_ipaddr_t", ""))
333		nvram_set("u2ec_busyip", nvram_safe_get("lan_ipaddr"));
334	else
335		nvram_set("u2ec_busyip", nvram_safe_get("lan_ipaddr_t"));
336
337	semaphore_post();
338
339        if( (childpid = fork() ) < 0)
340        {
341        }
342        else if(childpid == 0)
343        {
344		//syslog(LOG_NOTICE, "Printing %d\n", LPRflag);
345
346		if(LPRflag==0) processReq(clisockfd);
347#ifdef LPR_with_ASUS//JY1114
348		else if(LPRflag==1) processReq_LPR(clisockfd, 1);
349#endif
350#ifdef Raw_Printing_with_ASUS //Lisa
351		else if(LPRflag == 2) processReq_Raw(clisockfd);
352#endif
353		close(sockfd);
354		close(sockfd_ASUS);
355		close(netfd);
356        	exit(0);
357        }
358
359	//syslog(0, "Printing Process %d %d %d\n", busy, lptstatus.busy, childpid);
360
361        //parents process goes on here
362        //remark PRINT("fork -- childpid %d\n",childpid);
363
364	if(lptstatus.busy == FALSE)
365	{
366		lptstatus.busy = TRUE;
367//		busy = TRUE;				// remarked by Jiahao for U2EC. 20080808.
368		strcpy(lptstatus.addr , inet_ntoa(cli_addr.sin_addr));
369		lptstatus.pid = childpid;
370	}
371
372        close(clisockfd);
373    }
374
375}
376
377
378int processReq(int sockfd)
379{
380
381    char                recv_buf[4]; //buffer to receive header
382    static char         waittime = 1;
383    int                 iCount;
384    struct print_buffer pbuf;
385    char                chPortOpened = FALSE;
386
387    /***************************************/
388    /**  We reset the printer only when   **/
389    /**  user wants to cancel a job or    **/
390    /**  error occurs                     **/
391    /***************************************/
392
393    //Process the request from cleint
394    //return when error or job complete
395    while(TRUE)
396    {
397        LPT_CMD_PKT_HDR     *pHdrCmd  = NULL;
398        LPT_DATA_PKT_HDR    *pHdrData = NULL;
399        LPT_RES_PKT_HDR     pktRes;
400        WORD                body[1];
401        int                 rcv; //records how many bytes being received
402        char                *para_buf = NULL; //buffer to store parameter
403
404        memset(recv_buf,0,sizeof(recv_buf));
405        iCount = sizeof(recv_buf);
406
407        if(waittime < 5)
408        {
409            waittime ++;
410        }
411
412        //Receive the complete header here
413        while( iCount > 0 )
414        {
415            rcv = RECV(sockfd , recv_buf + (4 - iCount) , iCount , 60);
416
417            if( rcv < 1)
418            {
419                //receive error
420                //PRINT("1. rcv -> %d\n",rcv);
421
422                if(rcv < 0)
423                {
424                	//perror("ERR:");
425                }
426
427                closesocket(sockfd);
428                if(chPortOpened == TRUE)
429                {
430                    reset_printer(10);
431                }
432
433                return 0;
434            }
435
436            iCount = iCount - rcv;
437        }
438
439
440        //Check Service ID
441
442        switch(recv_buf[0])
443        {
444            case NET_SERVICE_ID_LPT_EMU:
445                //PRINT("Service ID -> NET_SERVICE_ID_LPT_EMU \n");
446                break;
447
448            default:
449                //PRINT("Service ID -> Not Supported \n");
450                closesocket(sockfd);
451                if(chPortOpened == TRUE)
452                {
453                    reset_printer(10);
454                }
455                return(0);
456                break;
457        }
458
459
460        //Check Packet Type
461
462        switch(recv_buf[1])
463        {
464            case NET_PACKET_TYPE_CMD:
465                //PRINT(">>> TYPE_CMD ");
466                pHdrCmd = (LPT_CMD_PKT_HDR *)recv_buf;
467                break;
468
469            case NET_PACKET_TYPE_RES:
470                //We should not recevice Response Packet in Server
471                //PRINT("Packet Type -> NET_PACKET_TYPE_RES Error!!! \n");
472                closesocket(sockfd);
473                if(chPortOpened == TRUE)
474                {
475                    reset_printer(10);
476                }
477                return(0);
478                break;
479
480            case NET_PACKET_TYPE_DATA:
481                //PRINT("$$$ TYPE_DATA ");
482                pHdrData = (LPT_DATA_PKT_HDR *)recv_buf;
483                break;
484
485            default:
486                //PRINT("Packet Type -> Not Supported \n");
487                closesocket(sockfd);
488                if(chPortOpened == TRUE)
489                {
490                    reset_printer(10);
491                }
492                return(0);
493                break;
494
495        }
496
497        if( pHdrCmd != NULL)
498        {
499            //We receive command
500
501            para_buf = NULL;
502
503            iCount = pHdrCmd->ParaLength;
504
505	    if (iCount!=0)
506	    {
507             	(void *)para_buf = malloc(pHdrCmd->ParaLength);
508            }
509
510	    //PRINT("HdrCmd Length %d\n", iCount);
511
512	    // para_buf may be NULL but this command still work
513	    // 2004/06/07 by Joey
514            if(iCount!=0 && para_buf == NULL)
515            {
516                //perror("malloc error 1:");
517                closesocket(sockfd);
518                if(chPortOpened == TRUE)
519                {
520                    reset_printer(10);
521                }
522                return(0);
523            }
524
525            while( iCount > 0 )
526            {
527                rcv = RECV(sockfd , (para_buf + (pHdrCmd->ParaLength - iCount )) , iCount , 30);
528
529                if( rcv < 1)
530                {
531                    //receive error
532                    //perror("2. RECV ERR:");
533                    closesocket(sockfd);
534                    free(para_buf);
535                    if(chPortOpened == TRUE)
536                    {
537                        reset_printer(10);
538                    }
539                    return 0;
540                }
541
542                iCount = iCount - rcv;
543            }
544
545
546            switch(pHdrCmd->CommandID)
547            {
548                case NET_CMD_ID_OPEN:
549                    //remark PRINT("NET_CMD_ID_OPEN\n");
550
551                    /************************************/
552                    /************************************/
553                    /*** TODO: add code here to check ***/
554                    /*** the printer status           ***/
555                    /************************************/
556                    /************************************/
557
558                    pktRes.ServiceID = NET_SERVICE_ID_LPT_EMU;
559                    pktRes.PacketType = NET_PACKET_TYPE_RES;
560                    pktRes.CommandID = NET_CMD_ID_OPEN;
561                    pktRes.ResLength = 2;
562
563                    if(busy == FALSE)
564                    {
565                        int prnstatus=0;
566		        FILE *statusFp = NULL;
567
568
569                        //remark PRINT("--------lptstatus.busy == FALSE\n");
570
571                        /* add by James Yeh to support usb printer */
572                        /* 2002/12/25 							   */
573
574
575                        check_par_usb_prn();
576
577                        //Open printer port -modified by PaN
578                        if(g_useUsb == TRUE)
579                        {
580                        	fdPRN = open("/dev/usb/lp0",O_RDWR);
581                        }
582                        else
583                        {
584                        	fdPRN = open("/dev/lp0",O_RDWR);
585                        }
586
587                        if(fdPRN == 0)
588                        {
589                            //Failed to open printer port
590                            //PRINT("Can not open lp0 errno -> %d \n",errno);
591                            //perror("ERR:");
592
593                            //Send header
594                            send(sockfd , (const char *)&pktRes , sizeof(pktRes) , 0);
595                            //Send body
596                            body[0] = ERR_SERVER_LPT_FAIL;
597                            send(sockfd , body , sizeof(body) , 0);
598                            free(para_buf);
599                            return(0);
600                        }
601
602                        ioctl(fdPRN,LPGETSTATUS,&prnstatus);
603
604                        if(prnstatus != 0)
605                        {
606                            //remark PRINT("prnstatus != 0\n");
607                            body[0] = ERR_SERVER_OCCUPIED;
608
609                            /*******************************************************************************/
610                            /* why we are using ERR_SERVER_OCCUPIED instead of ERR_SERVER_LPT_FAIL here ?? */
611                            /* Because ERR_SERVER_OCCUPIED will let user try again & again. Using          */
612                            /* ERR_SERVER_LPT_FAIL will fail the reques                                    */
613                            /*******************************************************************************/
614
615                            //Send header
616                            send(sockfd , (const char *)&pktRes , sizeof(pktRes) , 0);
617                            //Send body
618                            send(sockfd , body , sizeof(body) , 0);
619                            free(para_buf);
620                            return(0);
621                        }
622
623			            statusFp = fopen(STATUS_FILE , "w");
624
625            			if(statusFp != NULL)
626            			{
627                			fprintf(statusFp,"PRN_CLIENT=\"%s\"\n",lptstatus.addr);
628                			fclose(statusFp);
629            			}
630            			else
631            			{
632                			//perror("Open status file failed: ");
633            			}
634
635                        chPortOpened = TRUE;
636
637                        body[0] = ERR_SUCCESS;
638                    }
639                    else
640                    {
641                        //PRINT("*********lptstatus.busy == TRUE\n");
642                        body[0] = ERR_SERVER_OCCUPIED;
643
644                        //Send header
645                        send(sockfd , (const char *)&pktRes , sizeof(pktRes) , 0);
646                        //Send body
647                        send(sockfd , body , sizeof(body) , 0);
648                        free(para_buf);
649                        return(0);
650                    }
651
652                    //Send header
653                    send(sockfd , (const char *)&pktRes , sizeof(pktRes) , 0);
654                    //Send body
655                    send(sockfd , body , sizeof(body) , 0);
656
657                    break;
658
659                case NET_CMD_ID_CLOSE:
660                {
661                    char bCancel = FALSE;
662
663
664                    //remark PRINT("NET_CMD_ID_CLOSE\n");
665
666                    /*****************************************************/
667                    /* Check if user normally or abnormally end this job */
668                    /*                                 James 2002/06/05  */
669                    /*****************************************************/
670
671                    if(pHdrCmd->ParaLength != 1) //Length should be 1 byte long
672                    {
673                        //remark PRINT("NET_CMD_ID_CLOSE length error -- %d\n",pHdrCmd->ParaLength);
674                        closesocket(sockfd);
675                        free(para_buf);
676                        if(chPortOpened == TRUE)
677                        {
678                            reset_printer(10);
679                        }
680                        return(0);
681                    }
682
683                    //remark PRINT("para_buf[0] - %02X\n",para_buf[0]);
684
685                    if(para_buf[0] == 1)
686                    {
687                        bCancel = TRUE;
688                    }
689
690
691                    pktRes.ServiceID = NET_SERVICE_ID_LPT_EMU;
692                    pktRes.PacketType = NET_PACKET_TYPE_RES;
693                    pktRes.CommandID = NET_CMD_ID_CLOSE;
694                    pktRes.ResLength = 2;
695
696
697                    //Send header
698                    send(sockfd , (const char *)&pktRes , sizeof(pktRes) , 0);
699
700                    //Send body
701                    body[0] = ERR_SUCCESS;
702                    send(sockfd , body , sizeof(body) , 0);
703
704                    closesocket(sockfd);
705                    free(para_buf);
706
707                    //close printer port modified by PaN
708                    sleep(1);
709
710                    if(bCancel == TRUE)
711                    {
712                        //reset printer
713                        //PRINT("Reset Printer\n");
714                        reset_printer(10);
715                    }
716
717                    close(fdPRN);
718
719                    return(0);
720                    break;
721                }//case NET_CMD_ID_CLOSE:
722
723                case NET_CMD_ID_READ:
724                {
725                    LPT_DATA_PKT_HDR    pktData;
726                    WORD                len;
727                    int                 res_fread = 0;
728                    PBYTE               pReadbuf;
729
730                    len = (para_buf[1] << 8) + para_buf[0];
731
732                    //remark PRINT("NET_CMD_ID_READ len -> %d\n",len);
733
734                    /************************************/
735                    /************************************/
736                    /*** TODO: add code here to read  ***/
737                    /*** the printer port             ***/
738                    /************************************/
739                    /************************************/
740
741                    (void *)pReadbuf = malloc(len + 1);
742
743                    if(pReadbuf == NULL)
744                    {
745                        //perror("malloc error 2:");
746                        closesocket(sockfd);
747                        free(para_buf);
748                        if(chPortOpened == TRUE)
749                        {
750                            reset_printer(10);
751                        }
752                        return(0);
753                    }
754
755                    pbuf.len = len;
756                    pbuf.buf = pReadbuf;
757                    //PRINT("Start Read\n");
758                    res_fread = ioctl(fdPRN,LPREADDATA,&pbuf);
759                    //PRINT("End Read\n");
760                    //PRINT("---- res_fread %d\n",res_fread);
761
762                    if(res_fread > 0)
763                    {
764                        len = res_fread;
765                        pReadbuf[res_fread]= 0;
766                        //PRINT("*** %s\n",pReadbuf);
767                    }
768                    else
769                    {
770                        len = 0;
771                    }
772
773                    pktData.ServiceID = NET_SERVICE_ID_LPT_EMU;
774                    pktData.PacketType = NET_PACKET_TYPE_DATA;
775                    pktData.DataLength = len; //can not exceed 0xFFFF
776
777                    /**********    Sending Header     **********/
778                    send(sockfd , (const char *)&pktData , sizeof(pktData) , 0);
779
780                    if( len > 0)
781                    {
782                        /**********    Sending Body       **********/
783                        send(sockfd , (const char *)pReadbuf , len , 0);
784                    }
785                    free(pReadbuf);
786
787                    break;
788                }
789
790                free(para_buf);
791            }//switch(pHdrCmd->CommandID)
792        }//if( pHdrCmd != NULL)
793
794
795        if( pHdrData != NULL)
796        {
797            //We receive Data
798            int     res_fwrite;
799            int     res_total_fwrite;
800            int     write_len;
801            int     total_len;
802            PBYTE   write_buf;
803            int prnstatus=0;
804
805            iCount = pHdrData->DataLength;
806
807            if (iCount!=0)
808	    {
809            	(void *)para_buf = malloc(pHdrData->DataLength);
810            }
811            //remark
812	    //PRINT("pHdrData->DataLength -- %d\n",pHdrData->DataLength);
813
814            if(iCount!=0 && para_buf == NULL)
815            {
816                //perror("malloc error 3:");
817                closesocket(sockfd);
818                if(chPortOpened == TRUE)
819                {
820                    reset_printer(10);
821                }
822                return(0);
823            }
824
825            //PRINT("DATA HDR OK...\n");
826
827            while( iCount > 0 )
828            {
829                rcv = RECV(sockfd , (para_buf + (pHdrData->DataLength - iCount )) , iCount , 30);
830
831                if( rcv < 1)
832                {
833                    //receive error
834                    //perror("3. RECV ERR:");
835                    closesocket(sockfd);
836                    free(para_buf);
837                    if(chPortOpened == TRUE)
838                    {
839                        reset_printer(10);
840                    }
841                    return 0;
842                }
843
844                iCount = iCount - rcv;
845            }
846
847
848            //PRINT("DATA BODY OK...\n");
849
850            pbuf.len = pHdrData->DataLength;
851            pbuf.buf = para_buf;
852
853            write_len = 0;
854            total_len = pHdrData->DataLength;
855            write_buf = para_buf;
856            res_fwrite = 0;
857            res_total_fwrite = 0;
858
859            //remark PRINT("total_len %d\n",total_len);
860
861            while(total_len > 0)
862            {
863                if(total_len > 4096)
864                {
865                    pbuf.len = 4096;
866                    pbuf.buf = write_buf;
867                    res_fwrite = ioctl(fdPRN,LPWRITEDATA,&pbuf);
868
869                    if(res_fwrite != 4096)
870                    {
871                        DWORD retry = 0;
872
873                        ioctl(fdPRN,LPGETSTATUS,&prnstatus);
874
875                        //remark PRINT("prnstatus %d\n",prnstatus);
876
877                        while( ((prnstatus == 0) || (prnstatus & LP_PBUSY)) && (res_fwrite != 4096) && (retry < 3))
878                        {
879                            //remark PRINT("}}}}}}}}}}}} res_fwrite %d\n",res_fwrite);
880                            pbuf.len = 4096 - res_fwrite;
881                            pbuf.buf = &(write_buf[res_fwrite]);
882                            //usleep(500); //why we don't use usleep here ?? becuse usleep will sleep longer then we expect in iBox
883                            sleep(1);
884                            res_fwrite = res_fwrite + ioctl(fdPRN,LPWRITEDATA,&pbuf);
885                            //remark PRINT("}}}}}}}}}}}} res_fwrite %d\n",res_fwrite);
886                            ioctl(fdPRN,LPGETSTATUS,&prnstatus);
887
888                            //remark PRINT("retry %d\n",retry);
889                            retry ++;
890                        }
891
892                    }
893
894                    res_total_fwrite = res_total_fwrite + res_fwrite;
895
896                    if(res_fwrite != 4096)
897                    {
898                        break;
899                    }
900                    else
901                    {
902                        total_len = total_len - 4096;
903                        if(total_len == 0)
904                        {
905                            //remark PRINT("total_len == 0 \n");
906                            break;
907                        }
908                        write_buf = &(write_buf[4096]);
909                    }
910
911                    //remark PRINT("res_total_fwrite %d -- res_fwrite %d \n",res_total_fwrite,res_fwrite);
912
913                }
914                else
915                {
916                    pbuf.len = total_len;
917                    pbuf.buf = write_buf;
918                    res_fwrite = ioctl(fdPRN,LPWRITEDATA,&pbuf);
919
920                    //remark PRINT("PPPPPPP res_fwrite %d\n",res_fwrite);
921                    if(res_fwrite != total_len)
922                    {
923                        DWORD retry = 0;
924
925                        ioctl(fdPRN,LPGETSTATUS,&prnstatus);
926                        //remark PRINT("prnstatus %d\n",prnstatus);
927
928                        while( ((prnstatus == 0) || (prnstatus & LP_PBUSY))  && (res_fwrite != total_len) && (retry < 3))
929                        {
930                            pbuf.len = total_len - res_fwrite;
931                            pbuf.buf = &(write_buf[res_fwrite]);
932                            //usleep(500); //why we don't use usleep here ?? becuse usleep will sleep longer then we expect in iBox
933                            sleep(1);
934                            res_fwrite = res_fwrite + ioctl(fdPRN,LPWRITEDATA,&pbuf);
935                            //remark PRINT("}}}}}}}}}}}} res_fwrite %d\n",res_fwrite);
936                            ioctl(fdPRN,LPGETSTATUS,&prnstatus);
937                            //remark PRINT("retry %d\n",retry);
938                            retry ++;
939                        }
940
941                    }
942
943                    res_total_fwrite = res_total_fwrite + res_fwrite;
944                    //remark PRINT("res_total_fwrite %d -- res_fwrite %d \n",res_total_fwrite,res_fwrite);
945                    break;
946                }
947
948            }
949
950
951            //remark PRINT("WritePrint %d - %d bytes\n",res_total_fwrite,pHdrData->DataLength);
952
953            if(res_total_fwrite != pHdrData->DataLength)
954            {
955                int tmp=0;
956                //remark PRINT("res_total_fwrite != pHdrData->DataLength \n");
957                ioctl(fdPRN,LPGETSTATUS,&prnstatus);
958
959                //remark PRINT("prnstatus %08X \n",prnstatus);
960
961                if((prnstatus & LP_PERRORP) == 1 ) //Printer off-line
962                {
963                    //remark PRINT("Printer off-line -- prnstatus %d\n",prnstatus);
964                    res_total_fwrite = res_total_fwrite|0x8000;
965                }
966                else
967                {
968                    //remark PRINT("Paper Empty -- prnstatus %d\n",prnstatus);
969                    res_total_fwrite = res_total_fwrite|0x4000;
970                }
971		check_prn_status("BUSY or ERROR", clientaddr);
972            }
973            else{//JY1113 add
974/*JY1113*/
975		check_prn_status("Printing", clientaddr);
976/**/
977            }
978            //remark PRINT("res_total_fwrite %08X\n",res_total_fwrite);
979
980            body[0] = res_total_fwrite;
981
982            pktRes.ServiceID = NET_SERVICE_ID_LPT_EMU;
983            pktRes.PacketType = NET_PACKET_TYPE_RES;
984            pktRes.CommandID = NET_CMD_ID_DATA_RES;
985            pktRes.ResLength = 2;
986
987            //Send header
988            send(sockfd , (const char *)&pktRes , sizeof(pktRes) , 0);
989
990            //Send body
991            send(sockfd , body , sizeof(body) , 0);
992
993            free(para_buf);
994        }//if( pHdrData != NULL)
995    }
996    //remark PRINT("Thread Over\n");
997
998    return(0);
999
1000}
1001
1002
1003void sig_child(int sig)
1004{
1005    int childpid;
1006
1007    childpid = waitpid(-1, NULL , WNOHANG);
1008
1009    while( childpid > 0)
1010    {
1011
1012	//syslog(LOG_NOTICE, "sig child: %d\n", childpid);
1013    	//remark PRINT("sig_child %d\n",childpid);
1014
1015	    if( lptstatus.pid == childpid )
1016    	{
1017	        FILE *statusFp = NULL;
1018
1019        	statusFp = fopen(STATUS_FILE , "w");
1020
1021        	if(statusFp != NULL)
1022        	{
1023            		fprintf(statusFp,"PRN_CLIENT=\"\"\n");
1024            		fclose(statusFp);
1025        	}
1026        	else
1027        	{
1028            		//perror("Open status file failed: ");
1029        	}
1030
1031
1032    	    	/*** Wait 10 seconds here      ***/
1033        	/*** Because some slow printer ***/
1034        	/*** need some time to consume ***/
1035        	/*** the data...               ***/
1036        	sleep(10);
1037
1038        	lptstatus.busy = FALSE;
1039        	lptstatus.pid  = 0;
1040		check_prn_status(ONLINE, "");
1041
1042    	}
1043
1044    	childpid = waitpid(-1, NULL , WNOHANG);
1045	}
1046
1047   	//remark PRINT("waitpid -- childpid%d\n",childpid);
1048
1049}
1050
1051void sig_cleanup(int sig)
1052{
1053    //remark PRINT("sig_cleanup\n");
1054    exit(0);
1055}
1056
1057//JY1110
1058void sig_remove(int sig)
1059{
1060	if(lptstatus.pid != 0){
1061		kill(lptstatus.pid, SIGKILL);
1062	}
1063	else
1064		return;
1065}
1066
1067
1068int closesocket(int sockfd)
1069{
1070    //shutdown(sockfd,SHUT_RDWR);
1071    close(sockfd);
1072}
1073
1074/************************************/
1075/***  Receive the socket          ***/
1076/***  with a timeout value        ***/
1077/************************************/
1078DWORD RECV(int sockfd , PBYTE pRcvbuf , DWORD dwlen , DWORD timeout)
1079{
1080
1081    if( waitsock(sockfd , timeout , 0) == 0)
1082    {
1083        //timeout
1084        PRINT("RECV timeout %d\n",timeout);
1085        return -1;
1086    }
1087
1088    return recv(sockfd , pRcvbuf  , dwlen , 0 );
1089}
1090
1091
1092int waitsock(int sockfd , int sec , int usec)
1093{
1094    struct timeval  tv;
1095    fd_set          fdvar;
1096    int             res;
1097
1098    FD_ZERO(&fdvar);
1099    FD_SET(sockfd, &fdvar);
1100
1101    tv.tv_sec  = sec;
1102    tv.tv_usec = usec;
1103
1104    res = select( sockfd + 1 , &fdvar , NULL , NULL , &tv);
1105
1106    return res;
1107}
1108
1109void reset_printer(int sec)
1110{
1111    sleep(sec);
1112    ioctl(fdPRN,LPRESET);
1113}
1114
1115
1116/* to check use usb or parport printer */
1117/* James Yeh 2002/12/25 02:13	       */
1118int check_par_usb_prn()//JY: 20031104 change to int from void
1119{
1120    char    buf[1024];
1121    char    *token;
1122    FILE    *fp;
1123
1124#ifdef USBONLY
1125    g_useUsb = TRUE;
1126    return(g_useUsb);
1127#else
1128    fp=fopen("/proc/sys/dev/parport/parport0/devices/lp/deviceid","r");
1129
1130    if( fp != NULL)
1131    {
1132        while ( fgets(buf, sizeof(buf), fp) != NULL )
1133        {
1134            if(buf[0] == '\n')
1135            {
1136                //PRINT("skip empty line\n");
1137                continue;
1138            }
1139
1140            if(strncmp(buf , "status: " , strlen("status: "))   == 0)
1141            {
1142                token= buf + strlen("status: ");
1143
1144                //PRINT("token[0] %d\n",token[0]);
1145
1146//printf("token=%s\n", token);//JY1104
1147                if(token[0] == '0')
1148                {
1149                    g_useUsb = TRUE;
1150//printf("USB\n");//JY1112: delete
1151                }
1152                else
1153                {
1154                    g_useUsb = FALSE;
1155//printf("PARALLEL\n");//JY1112: delete
1156                }
1157			return(g_useUsb);//JY: 1104
1158                break;
1159            }
1160
1161        }
1162
1163        fclose(fp);
1164    }
1165#endif
1166
1167}
1168
1169/*1110test status
1170void checkstatus_usb_par()
1171{
1172	if(fd_print <= 0 || fd_print == NULL){
1173		check_prn_status("Off-line", "");
1174	}
1175	else {
1176		check_prn_status(ONLINE, "");
1177	}
1178}
1179*/
1180
1181/*JY1114: check printer status*/
1182void check_prn_status(char *status_prn, char *cliadd_prn)
1183{
1184	STATUSFILE=fopen("/var/state/printstatus.txt", "w");
1185	if(cliadd_prn == NULL)
1186	{
1187		fprintf(STATUSFILE, "PRINTER_USER=\"\"\n");
1188	}
1189	else
1190	{
1191		fprintf(STATUSFILE, "PRINTER_USER=\"%s\"\n", cliadd_prn);
1192	}
1193	fprintf(STATUSFILE, "PRINTER_STATUS=\"%s\"\n", status_prn);
1194	fclose(STATUSFILE);
1195	//strcpy(printerstatus, status_prn);
1196}
1197/*JY1114: get printer queue name for LPR*/
1198int get_queue_name(char *input)
1199{
1200	char QueueName_got[32];
1201	char *index1;
1202	int rps_i=0, rps_j=0;
1203	while(index1 = strrchr(input, ' '))
1204		index1[0] = 0;
1205	rps_i = 0;
1206	strcpy(QueueName_got, input);
1207	//return(strcmp(QueueName_got, "LPRServer"));
1208	//by pass queue Name Check
1209	return 0;
1210}
1211
1212/*JY1120: send ack*/
1213void send_ack_packet(int *talk, int ack)
1214{
1215	char buffertosend[SMALLBUFFER];
1216	buffertosend[0] = ack;
1217	buffertosend[1] = 0;
1218	//printf("send_ack_packet...\n");//JY1120: delete
1219	if( write( *talk, buffertosend, strlen(buffertosend) ) < 0 )
1220	{
1221		//printf("send_ack_packet: can not write socket...\n");
1222	}
1223}
1224
1225/*#######Lisa: Raw printing##########
1226 * open printer()
1227 * copy stream()
1228 * ProcessReq_Raw()
1229 ##################################*/
1230int open_printer(void)
1231{
1232        int		f;
1233
1234	check_par_usb_prn();
1235	if(g_useUsb==TRUE)
1236	{
1237		if ((f=open("/dev/usb/lp0",O_RDWR)) < 0 )
1238		{
1239			//syslog(LOGOPTS, "%s: %m\n", device);
1240			exit(1);
1241		}
1242	}
1243	else
1244	{
1245		if ((f=open("dev/lp0",O_RDWR)) < 0)
1246		{
1247//			syslog(LOGOPTS, "Open Parallel port error");
1248			exit(1);
1249		}
1250	}
1251	return (f);
1252}
1253
1254int copy_stream(int fd,int f)
1255{
1256	int		nread,nwrite;
1257	char		buffer[8192];
1258	int 		timeout=20, wait;
1259	int 		busyflag=0;
1260
1261	//PRINT("copy_stream\n");
1262	while ((nread = read(fd, buffer, sizeof(buffer))) > 0)
1263	{
1264		int index=0,countread;
1265
1266		// nwrite=fwrite(buffer, sizeof(char), nread, f);
1267                /* Lisa:fwrite => write */
1268 		check_prn_status("Printing", clientaddr);  //Add by Lisa
1269
1270		while	(index < nread )
1271		{
1272			countread=nread-index;
1273			nwrite=write(f, &buffer[index],countread);
1274
1275			if (nwrite<0)
1276			{
1277	     			logmessage("lpd", "write error : %d\n", errno);
1278				check_prn_status("Busy or Error", clientaddr);
1279				return(nread);
1280			}
1281#ifdef REMOVE
1282			else if (nwrite==0)
1283			{
1284	     			syslog(LOG_NOTICE, "write error 4: %d\n", nwrite);
1285				check_prn_status("Busy or Error",clientaddr);
1286				busyflag=1;
1287			}
1288#endif
1289			else if ((wait=waitsock(f,timeout,0))==0)
1290			{
1291	     			//logmessage("lpd", "write error %d\n", errno);
1292				check_prn_status("Busy or Error",clientaddr);
1293				busyflag=1;
1294			}
1295			else if(wait<0)
1296			{
1297	     			logmessage("lpd", "can not write : %d\n", errno);
1298				check_prn_status("Busy or Error",clientaddr);
1299				return(nread);
1300			}
1301			else
1302			{
1303				index+=nwrite;
1304
1305				if (busyflag==1)
1306				{
1307					busyflag = 0;
1308					check_prn_status("Printing",clientaddr);
1309				}
1310			}
1311		}
1312	}
1313	//(void)fflush(f);
1314        check_prn_status(ONLINE,""); //Add by Lisa
1315	return (nread);
1316}
1317
1318void processReq_Raw(int fd)
1319{
1320	int f1;
1321
1322	if (busy == FALSE)
1323	{
1324		if ((f1 = open_printer()) >= 0)   //modify by Lisa
1325		{
1326			if (copy_stream(fd, f1) < 0)
1327			{
1328				//syslog(0, "copy stream err\n");
1329			}
1330			close(f1);
1331		}
1332	}
1333	close(fd);
1334}
1335