Added README.
[irreco.git] / lirc-0.8.4a / contrib / lirc.m4
blob98f6c2033653c647f00728335e9a2c5ff4e553f8
1 ## lirc.m4 (Macros for autoconf)
2 ##
3 ## (C) 1999 Christoph Bartelmus (lirc@bartelmus.de)
4 ## 
6 #######################################################################
7 ##
8 ##   Check for LIRC
9 ##
10 #######################################################################
12 dnl AC_PATH_LIRC([MINIMUM-VERSION])
13 dnl Check for LIRC and define LIRCD
14 dnl
15 AC_DEFUN([AC_PATH_LIRC],
17   min_lirc_version=ifelse([$1], ,0.5.5,$1)
18   AC_MSG_CHECKING(for LIRC>=$min_lirc_version)
20   AC_CACHE_VAL(ac_cv_have_lirc,[
21     no_lirc=no
22     lirc_version=none
23     lirc_cross_compiling=no
25     if test ! -S /dev/lircd; then
26       LIRCD=/dev/null
27       no_lirc=yes
28     else
29       LIRCD=/dev/lircd
31       rm -f conf.lirc
32       ac_save_cflags="${CFLAGS}"
33       CFLAGS="$CFLAGS -DLIRCD=\"$LIRCD\""
34       AC_TRY_RUN(
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <fcntl.h>
41 #include <getopt.h>
42 #include <sys/socket.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <sys/un.h>
46 #include <errno.h>
47 #include <signal.h>
48 #include <limits.h>
50 #define PACKET_SIZE 256
51 /* three seconds */
52 #define TIMEOUT 3
54 int timeout=0;
56 void sigalrm(int sig)
58         timeout=1;
61 const char *read_string(int fd)
63         static char buffer[PACKET_SIZE+1]="";
64         char *end;
65         static int ptr=0;
66         ssize_t ret;
67                 
68         if(ptr>0)
69         {
70                 memmove(buffer,buffer+ptr,strlen(buffer+ptr)+1);
71                 ptr=strlen(buffer);
72                 end=strchr(buffer,'\n');
73         }
74         else
75         {
76                 end=NULL;
77         }
78         alarm(TIMEOUT);
79         while(end==NULL)
80         {
81                 if(PACKET_SIZE<=ptr)
82                 {
83                         ptr=0;
84                         return(NULL);
85                 }
86                 ret=read(fd,buffer+ptr,PACKET_SIZE-ptr);
88                 if(ret<=0 || timeout)
89                 {
90                         if(!timeout)
91                         {
92                                 alarm(0);
93                         }
94                         ptr=0;
95                         return(NULL);
96                 }
97                 buffer[ptr+ret]=0;
98                 ptr=strlen(buffer);
99                 end=strchr(buffer,'\n');
100         }
101         alarm(0);timeout=0;
103         end[0]=0;
104         ptr=strlen(buffer)+1;
105         return(buffer);
108 enum packet_state
110         P_BEGIN,
111         P_MESSAGE,
112         P_STATUS,
113         P_DATA,
114         P_N,
115         P_DATA_N,
116         P_END
119 char *get_version(int fd,const char *packet)
121         int done,todo;
122         const char *string,*data;
123         char *endptr;
124         enum packet_state state;
125         int status,n;
126         unsigned long data_n;
127         unsigned int major,minor,micro;
128         static char version[100];
130         todo=strlen(packet);
131         data=packet;
132         while(todo>0)
133         {
134                 done=write(fd,(void *) data,todo);
135                 if(done<0)
136                 {
137                         return(NULL);
138                 }
139                 data+=done;
140                 todo-=done;
141         }
143         /* get response */
144         status=0;
145         state=P_BEGIN;
146         n=0;
147         while(1)
148         {
149                 string=read_string(fd);
150                 if(string==NULL) return(NULL);
151                 switch(state)
152                 {
153                 case P_BEGIN:
154                         if(strcasecmp(string,"BEGIN")!=0)
155                         {
156                                 continue;
157                         }
158                         state=P_MESSAGE;
159                         break;
160                 case P_MESSAGE:
161                         if(strncasecmp(string,packet,strlen(string))!=0 ||
162                            strlen(string)+1!=strlen(packet))
163                         {
164                                 state=P_BEGIN;
165                                 continue;
166                         }
167                         state=P_STATUS;
168                         break;
169                 case P_STATUS:
170                         if(strcasecmp(string,"SUCCESS")==0)
171                         {
172                                 status=0;
173                         }
174                         else if(strcasecmp(string,"END")==0)
175                         {
176                                 status=0;
177                                 return(NULL);
178                         }
179                         else if(strcasecmp(string,"ERROR")==0)
180                         {
181                                 status=-1;
182                         }
183                         else
184                         {
185                                 goto bad_packet;
186                         }
187                         state=P_DATA;
188                         break;
189                 case P_DATA:
190                         if(strcasecmp(string,"END")==0)
191                         {
192                                 return(NULL);
193                         }
194                         else if(strcasecmp(string,"DATA")==0)
195                         {
196                                 state=P_N;
197                                 break;
198                         }
199                         goto bad_packet;
200                 case P_N:
201                         errno=0;
202                         data_n=strtoul(string,&endptr,0);
203                         if(!*string || *endptr)
204                         {
205                                 goto bad_packet;
206                         }
207                         if(data_n==0)
208                         {
209                                 state=P_END;
210                         }
211                         else
212                         {
213                                 state=P_DATA_N;
214                         }
215                         break;
216                 case P_DATA_N:
217                         if(data_n==1 && status==0)
218                         {
219                                 if(sscanf(string,"%u.%u.%u",
220                                           &major,&minor,&micro)==3)
221                                 {
222                                         sprintf(version,"%u.%u.%u",
223                                                 major,minor,micro);
224                                 }
225                                 else
226                                 {
227                                         goto bad_packet;
228                                 }
229                         }
230                         n++;
231                         if(n==data_n) state=P_END;
232                         break;
233                 case P_END:
234                         if(strcasecmp(string,"END")==0)
235                         {
236                                 return(version);
237                         }
238                         goto bad_packet;
239                         break;
240                 }
241         }
242  bad_packet:
243         return(NULL);
246 int main(int argc,char **argv)
248         char *version,*min_version;
249         unsigned int major,minor,micro,min_major,min_minor,min_micro;
250         struct sockaddr_un addr;
251         FILE *result;
252         int fd;
253         struct sigaction act;
255         result=fopen("conf.lirc","w");
256         if(result==NULL) exit(EXIT_FAILURE);
257         
258         act.sa_handler=sigalrm;
259         sigemptyset(&act.sa_mask);
260         act.sa_flags=0;           /* we need EINTR */
261         sigaction(SIGALRM,&act,NULL);
263         addr.sun_family=AF_UNIX;
264         strcpy(addr.sun_path,LIRCD);
265         fd=socket(AF_UNIX,SOCK_STREAM,0);
266         if(fd==-1)
267         {
268                 fprintf(result,"unknown");
269                 fclose(result);
270                 close(fd);
271                 exit(EXIT_FAILURE);
272         };
273         if(connect(fd,(struct sockaddr *)&addr,sizeof(addr))==-1)
274         {
275                 fprintf(result,"unknown");
276                 fclose(result);
277                 close(fd);
278                 exit(EXIT_FAILURE);
279         };
281         version=get_version(fd,"VERSION\n");
282         if(version==NULL)
283         {
284                 fprintf(result,"<0.5.5");
285                 fclose(result);
286                 close(fd);
287                 exit(EXIT_FAILURE);
288         }
289         fprintf(result,"%s",version);
290         fclose(result);
291         close(fd);
293         /* HP/UX 9 (%@#!) writes to sscanf strings */
295         min_version=strdup("$min_lirc_version");
296         if(min_version==NULL) exit(EXIT_FAILURE);
298         if(sscanf(version,"%u.%u.%u",&major,&minor,&micro)!=3 ||
299            sscanf(min_version,"%u.%u.%u",&min_major,&min_minor,&min_micro)!=3)
300         {
301                 exit(EXIT_FAILURE);
302         }
303         if(major<min_major ||
304            (major==min_major && minor<min_minor) ||
305            (major==min_major && minor==min_minor && micro<min_micro))
306         {
307                 exit(EXIT_FAILURE);
308         }
310         exit(EXIT_SUCCESS);
313         if test -f conf.lirc; then
314           lirc_version=`cat conf.lirc`
316 ##        lirc_major_version=`cat lirc.conf | \
317 ##          sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
318 ##        lirc_minor_version=`cat lirc.conf | \
319 ##          sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
320 ##        lirc_micro_version=`cat lirc.conf | \
321 ##          sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
322         else
323           no_lirc=yes
324         fi,
325         no_lirc=yes
326         if test -f conf.lirc; then
327           lirc_version=`cat conf.lirc`
328         else
329           lirc_version=none
330         fi
331         ,lirc_cross_compiling=yes
332       )
333 ## AC_TRY_RUN()      
334       rm -f conf.lirc
335       CFLAGS="$ac_save_CFLAGS"
336     fi
337     ac_cv_have_lirc="no_lirc=${no_lirc} lirc_version=\"${lirc_version}\" \
338                      lirc_cross_compiling=${lirc_cross_compiling} \
339                      LIRCD=${LIRCD}"
340   ])
341 ## AC_CACHE_VAL
343   eval "$ac_cv_have_lirc"
345   if test x${no_lirc} = xyes; then
346     if test x${lirc_version} = xunknown; then
347       AC_MSG_RESULT([missing (lircd not running ?)])
348     elif test x${lirc_version} != xnone; then
349       AC_MSG_RESULT([missing (found lirc-${lirc_version})])
350     else
351       AC_MSG_RESULT(missing)
352     fi
353   else
354     if test x${lirc_cross_compiling} = xyes; then
355       AC_MSG_RESULT(found)
356     else
357       AC_MSG_RESULT([found lirc-${lirc_version}])
358     fi
359   fi
361   AC_DEFINE_UNQUOTED(LIRCD,"${LIRCD}")