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