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