1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <signal.h>
6#include <sys/types.h>
7#include <sys/time.h>
8#include <sys/wait.h>
9#include <sys/socket.h>
10#include <netinet/in.h>
11#include <arpa/inet.h>
12#include <errno.h>
13#include <fcntl.h>
14#include <arpa/inet.h>
15#include <net/if.h>
16#include <sys/ioctl.h>
17
18#include <bcmnvram.h>
19#include "iboxcom.h"
20#include "lp.h"
21
22#include <rtconfig.h>
23#include <shutils.h>
24
25#define SRV_PORT 9999
26#define PRINT(fmt, args...) fprintf(stderr, fmt, ## args)
27#define TRUE     1
28
29//#define WLANCFG "/etc/thttpd/www/cgi-bin/wlan.cfg"
30#define WLANCFG "/etc/linuxigd/WLANConfig11b"
31#define PRODUCTCFG "/etc/linuxigd/general.log"
32#define LAN_DEV "br0"
33
34DWORD RECV(int sockfd , PBYTE pRcvbuf , DWORD dwlen , struct sockaddr *from, int *fromlen , DWORD timeout);
35int waitsock(int sockfd , int sec , int usec);
36int closesocket(int sockfd);
37void readPrnID(char *prninfo);
38void readParPrnID(char  *prninfo);
39void readUsbPrnID(char  *prninfo);
40int check_par_usb_prn(void);
41int  set_pid(int pid);	//deliver process id to driver
42void sig_usr1(int sig);	//signal handler to handle signal send from driver
43void sig_usr2(int sig);
44
45int timeup=0;
46
47/* global variables for interface settings */
48/* add by James Yeh 2002/12/23	     */
49#define MAX_INTERFACE   5
50int	g_intfCount = 0;
51char*	g_intf[MAX_INTERFACE];
52
53#define MAX_GETID_RETRY 10
54int	g_retry = 0;
55
56char ssid_g[32];
57char netmask_g[32];
58char productid_g[32];
59char firmver_g[16];
60unsigned char mac[6] = { 0x00, 0x0c, 0x6e, 0xbd, 0xf3, 0xc5};
61
62void sig_do_nothing(int sig)
63{
64}
65
66void load_sysparam(void)
67{
68	char *p, macstr[32];
69#if defined(RTCONFIG_WIRELESSREPEATER) || defined(RTCONFIG_PROXYSTA)
70	char tmp[100], prefix[] = "wlXXXXXXXXXXXXXX";
71#endif
72#ifdef RTCONFIG_WIRELESSREPEATER
73	if (nvram_get_int("sw_mode") == SW_MODE_REPEATER)
74	{
75		snprintf(prefix, sizeof(prefix), "wl%d.1_", nvram_get_int("wlc_band"));
76		strncpy(ssid_g, nvram_safe_get(strcat_r(prefix, "ssid", tmp)), sizeof(ssid_g));
77	}
78	else
79#endif
80#ifdef RTCONFIG_BCMWL6
81#ifdef RTCONFIG_PROXYSTA
82	if (is_psta(nvram_get_int("wlc_band")) || is_psr(nvram_get_int("wlc_band")))
83	{
84		snprintf(prefix, sizeof(prefix), "wl%d_", 1 - nvram_get_int("wlc_band"));
85		strncpy(ssid_g, nvram_safe_get(strcat_r(prefix, "ssid", tmp)), 32);
86	}
87	else
88#endif
89#endif
90	strncpy(ssid_g, nvram_safe_get("wl0_ssid"), sizeof(ssid_g));
91	strncpy(netmask_g, nvram_safe_get("lan_netmask"), sizeof(netmask_g));
92	strncpy(productid_g, get_productid(), sizeof(productid_g));
93
94	snprintf(firmver_g, sizeof(firmver_g), "%s.%s", nvram_safe_get("firmver"), nvram_safe_get("buildno"));
95
96	strcpy(macstr, nvram_safe_get("lan_hwaddr"));
97//	printf("mac: %d\n", strlen(macstr));
98	if (strlen(macstr)!=0) ether_atoe(macstr, mac);
99}
100
101int main(int argc , char* argv[])
102{
103	int	sockfd;
104	struct	sockaddr_in  serv_addr,cli_addr;
105	int	broadcast = 1;
106	int	count = 0;
107	struct timeval  tv;
108
109	if (argc < 2)
110	{
111		printf("not enough parameters for infosvr\n");
112		printf("infosvr netif...\n");
113		exit(0);
114	}
115
116	// Write PID file
117	if (!set_pid(getpid())) // Add by Joey
118	{
119		printf("can not set process id\n");
120		exit(0);
121	}
122
123	// Load system related static parameter
124	load_sysparam();
125
126#ifdef PRNINFO //JYWeng: 20030325 for WL500g/WL500b
127	// Signal for reading Printer Information
128	signal(SIGALRM, sig_usr1); // Add by Joey
129	signal(SIGUSR1 , sig_usr1);
130	alarm(2);		       // Get ID for the first time 2 seconds later
131#endif
132/*
133	signal(SIGUSR1, sig_do_nothing);
134*/
135	signal(SIGUSR2, sig_do_nothing);
136
137	g_intfCount = argc - 1;
138
139	while (count < g_intfCount)
140	{
141		g_intf[count]  = argv[count+1];
142		count ++;
143	}
144
145	if ((sockfd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
146	{
147		PRINT("can't open datagram socket\n");
148		perror("socket:");
149		exit(0);
150	}
151
152	if (setsockopt(sockfd , SOL_SOCKET , SO_BROADCAST ,(char *)&broadcast,sizeof(broadcast)) == -1)
153	{
154		perror("setsockopt:");
155	}
156
157	bzero((char *)&cli_addr , sizeof(cli_addr));
158	cli_addr.sin_family		= AF_INET;
159	cli_addr.sin_addr.s_addr	= inet_addr("255.255.255.255");
160	cli_addr.sin_port		= htons(SRV_PORT);
161
162	bzero((char *)&serv_addr , sizeof(serv_addr));
163	serv_addr.sin_family		= AF_INET;
164	serv_addr.sin_addr.s_addr	= htonl(INADDR_ANY);
165	serv_addr.sin_port		= htons(SRV_PORT);
166
167	int flag=1;
168	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag));
169	if (bind(sockfd,(struct sockaddr *)&serv_addr , sizeof(serv_addr)) < 0)
170	{
171		PRINT("can't bind\n");
172		perror("ERR:");
173		exit(0);
174	}
175
176	while (TRUE)
177	{
178		int     res;
179		fd_set  fdvar;
180
181		FD_ZERO(&fdvar);
182		FD_SET(sockfd, &fdvar);
183
184		tv.tv_sec  = 2;
185		tv.tv_usec = 0;
186		res = select( sockfd + 1 , &fdvar , NULL , NULL , &tv);
187
188		if (res == 1)
189		{
190//			printf("got packet\n");
191			processReq(sockfd);
192		}
193	}
194}
195
196int processReq(int sockfd)
197{
198//    IBOX_COMM_PKT_HDR*  phdr;
199    int		 /*iLen , iRes , iCount , */iRcv;
200    int		 fromlen;
201    char		*hdr;
202    char		pdubuf[INFO_PDU_LENGTH];
203    struct sockaddr_in  from_addr;
204    unsigned short cli_port;
205
206    memset(pdubuf,0,sizeof(pdubuf));
207
208    //PRINT("Enter processReq\n");
209
210    if ( waitsock(sockfd , 1 , 0) == 0)
211    {
212	return -1;
213    }
214
215    fromlen = sizeof(from_addr);
216
217    //Receive the complete PDU
218    iRcv = RECV(sockfd , pdubuf , INFO_PDU_LENGTH , (struct sockaddr *)&from_addr , &fromlen  , 1);
219
220    if (iRcv != INFO_PDU_LENGTH)
221    {
222	closesocket(sockfd);
223	return (-1);
224    }
225
226    hdr = pdubuf;
227    cli_port = ntohs(from_addr.sin_port);
228    //_dprintf("[InfoSvr] Client Port: %d\n", cli_port);
229    processPacket(sockfd, hdr, cli_port);
230/*						J++
231    closesocket(sockfd);
232*/
233}
234
235/************************************/
236/***  Receive the socket	  ***/
237/***  with a timeout value	***/
238/************************************/
239DWORD RECV(int sockfd , PBYTE pRcvbuf , DWORD dwlen , struct sockaddr *from, int *fromlen , DWORD timeout)
240{
241    if ( waitsock(sockfd , timeout , 0) == 0)
242    {
243	//timeout
244	PRINT("RECV timeout %d\n",timeout);
245	return -1;
246    }
247
248    return recvfrom(sockfd, pRcvbuf , dwlen , 0 , from , fromlen );
249}
250
251
252int waitsock(int sockfd , int sec , int usec)
253{
254    struct timeval  tv;
255    fd_set	  fdvar;
256    int	     res;
257
258    FD_ZERO(&fdvar);
259    FD_SET(sockfd, &fdvar);
260
261    tv.tv_sec  = sec;
262    tv.tv_usec = usec;
263
264    res = select( sockfd + 1 , &fdvar , NULL , NULL , &tv);
265
266    return res;
267}
268
269int closesocket(int sockfd)
270{
271    /* Clear the UDP socket */
272    char dummy[1024];
273    int  iLen , res;
274
275    //PRINT("closesocket ... \n");
276
277    res = waitsock(sockfd , 1 , 0);
278
279    //PRINT("waitsock res %d\n",res);
280
281    if (res == 1)
282    {
283	iLen  = recvfrom(sockfd, dummy , sizeof(dummy) , 0,NULL,0 );
284    }
285    else
286    {
287	iLen = 0;
288    }
289
290    //PRINT("iLen %d\n",iLen);
291
292    if (iLen == sizeof(dummy))
293    {
294	res = waitsock(sockfd , 1 , 0);
295    }
296    else
297    {
298	return 0;
299    }
300
301    while (res == 1)
302    {
303	iLen  = recvfrom(sockfd, dummy , sizeof(dummy) , 0,NULL,0 );
304	//PRINT("iLen = %d\n",res);
305	res = waitsock(sockfd , 0 , 100);
306    }
307
308    return 0;
309}
310
311
312void readPrnID(char *prninfo)
313{
314//    char    *token;
315
316    if (check_par_usb_prn() == TRUE) //uese USB when return TRUE
317    {
318	readUsbPrnID(prninfo);
319    }
320    else
321    {
322	readParPrnID(prninfo);
323    }
324}
325
326void deCR(char *str)
327{
328	int i, len;
329
330	len = strlen(str);
331	for (i=0; i<len; i++)
332	{
333		if (*(str+i) == '\r' || *(str+i) == '\n', *(str+i) == '"')
334		{
335			*(str+i) = 0;
336			break;
337		}
338	}
339}
340
341void readUsbPrnID(char  *prninfo)
342{
343    char				mfr[32];
344    char				model[64];
345    int				 fd;
346    struct parport_splink_device_info   prn_info;
347
348
349//    PRINT("readUsbPrnID\n");	// nosiy...
350
351    if ( (fd=open("/dev/usb/lp0", O_RDWR)) < 0 ) //Someone is opening the usb lp0
352    {
353	FILE *fp;
354
355	fp=fopen("/proc/usblp/usblpid","r");
356
357	if ( fp != NULL)
358	{
359	    ///
360//	    char *tokenEntry;
361//	    char *tokenField;
362//	    char *manufac;
363//	    char *mod;
364	    char buf[1024];
365	    char *token;
366
367	    memset(mfr , 0 , sizeof(mfr));
368	    memset(model , 0 , sizeof(model));
369
370	    while ( fgets(buf, sizeof(buf), fp) != NULL )
371	    {
372		if (buf[0] == '\n')
373		{
374		    PRINT("skip empty line\n");
375		    continue;
376		}
377
378		if (strncmp(buf , "Manufacturer=" , strlen("Manufacturer=")) == 0)
379		{
380		    token= buf + strlen("Manufacturer=");
381		    PRINT("Manufacturer token %s",token);
382
383		    memccpy(mfr , token , '\n' , 31);
384					deCR(mfr);
385		}
386
387		if (strncmp(buf , "Model=" , strlen("Model=")) == 0)
388		{
389		    token= buf + strlen("Model=");
390		    PRINT("Model token %s",token);
391
392		    memccpy(model   , token , '\n' , 63);
393					deCR(model);
394		}
395	    }
396
397	    fclose(fp);
398
399	    sprintf( prninfo , "%s %s", mfr , model );
400
401	    PRINT("PRINTER MODEL %s\n",prninfo);
402	}
403	else
404	{
405	    sprintf( prninfo , "  " );
406//	    PRINT("open failed\n");	// noisy...
407	}
408    }
409    else
410    {
411	if ( ioctl(fd, LPGETID, &prn_info) <0 )
412	{
413	    PRINT("ioctl error\n");
414	    perror("ioctl");
415	}
416	else
417	{
418//	    int  i = 0;
419
420	    //PRINT("manufacturer: %s\n",prn_info.mfr);
421	    //PRINT("model: %s\n",prn_info.model);
422	    //PRINT("class: %s\n",prn_info.class_name);
423	    //PRINT("description: %s\n",prn_info.description);
424
425	    memccpy(mfr , prn_info.mfr , 1 , 32);
426	    memccpy(model , prn_info.model , 1 , 32);
427
428	    sprintf( prninfo , "%s %s", mfr , model );
429
430	    PRINT("prninfo %s",prninfo);
431	}
432
433	close(fd);
434    }
435}
436
437
438void readParPrnID(char  *prninfo)
439{
440    char				mfr[32];
441    char				model[64];
442    int				 fd;
443    struct parport_splink_device_info   prn_info;
444
445
446    PRINT("readParPrnID\n");
447
448    if ( (fd=open("/dev/lp0", O_RDWR)) < 0 ) //Someone is opening the lp0
449    {
450	FILE *fp;
451
452	fp=fopen("/proc/sys/dev/parport/parport0/devices/lp/deviceid","r");
453
454	if ( fp != NULL)
455	{
456	    ///
457//	    char *tokenEntry;
458//	    char *tokenField;
459//	    char *manufac;
460//	    char *mod;
461	    char buf[1024];
462	    char *token;
463
464	    memset(mfr , 0 , sizeof(mfr));
465	    memset(model , 0 , sizeof(model));
466
467	    while ( fgets(buf, sizeof(buf), fp) != NULL )
468	    {
469		if (buf[0] == '\n')
470		{
471		    PRINT("skip empty line\n");
472		    continue;
473		}
474
475		if (strncmp(buf , "Manufacturer: " , strlen("Manufacturer: ")) == 0)
476		{
477		    token= buf + strlen("Manufacturer: ");
478		    PRINT("Manufacturer token %s",token);
479
480		    memccpy(mfr , token , '\n' , 31);
481					deCR(mfr);
482		}
483
484		if (strncmp(buf , "Model: " , strlen("Model: ")) == 0)
485		{
486		    token= buf + strlen("Model: ");
487		    PRINT("Model token %s",token);
488
489		    memccpy(model   , token , '\n' , 63);
490					deCR(model);
491		}
492	    }
493
494	    fclose(fp);
495
496	    sprintf( prninfo , "%s %s", mfr , model );
497
498	    PRINT("prninfo %s\n",prninfo);
499	}
500	else
501	{
502	    sprintf( prninfo , "  " );
503	    PRINT("open failed\n");
504	}
505    }
506    else
507    {
508	if ( ioctl(fd, LPGETID, &prn_info) <0 )
509	{
510	    //PRINT("ioctl error\n");
511	}
512	else
513	{
514//	    int  i = 0;
515
516	    //PRINT("manufacturer: %s\n",prn_info.mfr);
517	    //PRINT("model: %s\n",prn_info.model);
518	    //PRINT("class: %s\n",prn_info.class_name);
519	    //PRINT("description: %s\n",prn_info.description);
520
521	    memccpy(mfr , prn_info.mfr , 1 , 32);
522	    memccpy(model , prn_info.model , 1 , 32);
523
524	    sprintf( prninfo , "%s %s", mfr , model );
525	}
526
527	close(fd);
528    }
529}
530
531#ifdef PRNINFO
532#define ONLINE_STRING "On-Line"
533#define OFFLINE_STRING "Off-Line"
534
535void readPrnStatus(void)
536{
537    FILE    *fp;
538    char    buf[64];
539    char    *ukeyword="PRINTER_USER=\"";
540    char    *skeyword="PRINTER_STATUS=\"";
541    char    *token;
542    char    user[32];
543    char    status[32];
544
545    fp = fopen("/var/state/printstatus.txt", "r");
546
547    memset(user, 0, sizeof(user));
548    memset(status, 0, sizeof(status));
549
550    if (fp!=NULL)
551    {
552	    while ( fgets(buf, sizeof(buf), fp) != NULL )
553	    {
554		if (buf[0] == '\n')
555		{
556		    PRINT("skip empty line\n");
557		    continue;
558		}
559
560		if (strncmp(buf , ukeyword , strlen(ukeyword)) == 0)
561		{
562		    token= buf + strlen(ukeyword);
563		    PRINT("User token %s",token);
564
565		    deCR(token);
566		    strcpy(user, token);
567		}
568		else if (strncmp(buf , skeyword, strlen(skeyword)) == 0)
569		{
570		    token= buf + strlen(skeyword);
571		    PRINT("Status token %s",token);
572
573		    deCR(token);
574		    strcpy(status, token);
575		}
576	    }
577	    fclose(fp);
578    }
579    else strcpy(status, ONLINE_STRING);
580    nvram_set("printer_status_t", status);
581    nvram_set("printer_user_t", user);
582
583    return;
584}
585
586/* update current status of printer */
587void sig_usr1(int sig)
588{
589    char    prninfo[256]/*, status[32]*/;
590    int isUsb;
591
592    //fp=fopen("/etc/linuxigd/printer.log","w");
593
594    memset( prninfo , 0 , sizeof(prninfo) );
595
596
597    if (check_par_usb_prn() == TRUE) //uese USB when return TRUE
598    {
599	    //fputs( "INTERFACE=USB\n" , fp );
600	    nvram_set("printer_ifname", "usb");
601	    readUsbPrnID(prninfo);
602	    isUsb = 1;
603    }
604    else
605    {
606	    // Goto this step, then printer must be turn on
607	    //fputs( "INTERFACE=PAR\n" , fp );
608	    nvram_set("printer_ifname", "par");
609	    readParPrnID(prninfo);
610	    isUsb = 0;
611    }
612
613    if (strcmp(prninfo, "  ")==0 || strlen(prninfo)==0)
614    {
615		//fprintf(fp, "MODEL=\"\"\n");
616		nvram_set("printer_model_t", "");
617
618		if (!isUsb)
619		{
620			/* Retry, only when paraport is plugged and no device id is returned */
621			printf("Try again 2 seconds later\n");
622			g_retry++;
623
624			if (g_retry<MAX_GETID_RETRY) alarm(6);
625			else g_retry = 0;
626		}
627    }
628    else
629    {
630		//fprintf(fp, "MODEL=\"%s\"\n", prninfo);
631		nvram_set("printer_model_t", prninfo);
632    }
633
634    /* update status of printer */
635    if (nvram_invmatch("printer_model_t", ""))
636    {
637		readPrnStatus();
638    }
639    else
640    {
641		nvram_set("printer_status_t", "");
642		nvram_set("printer_user_t", "");
643    }
644//    PRINT("Enter sig_usr1\n");	// nosiy...
645}
646#endif
647
648/* to check use usb or parport printer */
649/* return TRUE when using USB		   */
650/* James Yeh 2002/12/25 02:13	       */
651
652int check_par_usb_prn()
653{
654//    char    buf[1024];
655//    char    *token;
656//    FILE    *fp;
657
658#ifdef NO_PARALLEL
659    return TRUE;
660#else
661    fp=fopen("/proc/sys/dev/parport/parport0/devices/lp/deviceid","r");
662
663    if ( fp != NULL)
664    {
665	while ( fgets(buf, sizeof(buf), fp) != NULL )
666	{
667
668	    PRINT("lp:%s\n", buf);
669
670	    if (buf[0] == '\n')
671	    {
672		continue;
673	    }
674
675	    if (strncmp(buf , "status: " , strlen("status: ")) == 0)
676	    {
677		token= buf + strlen("status: ");
678
679		PRINT("token[0] %d\n",token[0]);
680
681			fclose(fp);
682
683		if (token[0] == '0')
684		{
685		    return (TRUE);
686		}
687		else
688		{
689		    return (0);
690		}
691		break;
692	    }
693	}
694
695	fclose(fp);
696    }
697#endif
698}
699
700
701/* Deliver pid to driver */
702/* Add by Joey	   */
703int set_pid(int pid)
704{
705	FILE *fp;
706//	int	fd, ret=0;
707//	struct print_buffer pb;
708
709#ifndef NO_PARALLEL
710	fd = open("/dev/lp0", O_RDWR);
711
712	if (fd<0) return 0;
713
714	if ((pb.buf = malloc(12)) == NULL) return 0;
715
716	sprintf(pb.buf, "%d", pid);
717
718	if (ioctl(fd, LPSETID, &pb)<0)
719	{
720	    free(pb.buf);
721		return 0;
722	}
723	free(pb.buf);
724
725	close(fd);
726#endif
727
728	fp = fopen("/var/run/infosvr.pid", "w");
729	fprintf(fp, "%d", pid);
730	fclose(fp);
731
732	return 1;
733}
734
735void sendInfo(int sockfd, char *pdubuf, unsigned short cli_port)
736{
737    struct sockaddr_in		  cli;
738//    IBOX_COMM_PKT_HDR		   hdr;
739    int count=0, err;
740
741    cli.sin_family    = AF_INET;
742    cli.sin_addr.s_addr = inet_addr("255.255.255.255");;
743    //cli.sin_port = htons(SRV_PORT);
744    cli.sin_port = htons(cli_port);
745
746    while (count < g_intfCount)
747    {
748	//PRINT("g_intf[%d] %s\n",count,g_intf[count]);
749	err = setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, g_intf[count] , IFNAMSIZ);
750	if (err != 0)
751	{
752	    printf("%s\n",g_intf[count]);
753	    perror("setsockopt:");
754	}
755
756	if (sendto(sockfd , pdubuf , INFO_PDU_LENGTH , 0 ,(struct sockaddr *) &cli, sizeof(cli)) == -1)
757	{
758	    perror("sendto:");
759	}
760	count ++;
761    }
762
763    err = setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, "" , IFNAMSIZ);
764
765    if (err != 0)
766    {
767	perror("setsockopt reset:");
768    }
769}
770