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