Mostly minor fixes up until version 0.8.10.
[irreco.git] / irtrans / irserver / src / ascii.c
blobd2003356c6700dfc035d0f9ededd7e91e678d100
1 /*
2 * Copyright (c) 2007, IRTrans GmbH
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of IRTrans GmbH nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY IRTrans GmbH ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL IRTrans GmbH BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifdef WIN32
30 #include "winsock2.h"
31 #include <windows.h>
32 #include <io.h>
33 #include <direct.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <time.h>
37 #include <sys/timeb.h>
39 #define MSG_NOSIGNAL 0
40 #endif
42 #ifdef WINCE
43 #include "winsock2.h"
44 #include <windows.h>
45 #include <time.h>
46 #endif
48 #include <stdio.h>
50 #ifdef LINUX
51 #include <stdlib.h>
52 #include <sys/types.h>
53 #include <sys/socket.h>
54 #include <netinet/in.h>
55 #include <sys/un.h>
56 #include <arpa/inet.h>
57 #include <dirent.h>
58 #include <sys/stat.h>
59 #include <errno.h>
60 #include <fcntl.h>
61 #include <signal.h>
62 #include <stdint.h>
63 #include <time.h>
65 typedef int SOCKET;
66 typedef int DWORD;
67 typedef int WSAEVENT;
68 #define closesocket close
69 #endif
72 #include "remote.h"
73 #include "errcode.h"
74 #include "network.h"
75 #include "dbstruct.h"
76 #include "lowlevel.h"
77 #include "fileio.h"
78 #include "global.h"
79 #include "flash.h"
81 #ifdef WIN32
82 #include "winio.h"
83 #include "winusbio.h"
84 BOOL WINAPI ShutdownHandler (DWORD type);
85 extern WSAEVENT IrtLanEvent;
86 #endif
88 extern int protocol_version;
89 int AnalyzeUDPString (char *st,int *netcom,char *remote,char *command,char *ccf,int *netmask,int *bus,int *led,int *port);
91 void CloseIRSocket (int client);
92 int FlashHTML (byte *command,byte result[]);
93 int GetHTMLFileList (byte *command,byte result[]);
94 int IRTransLanFlash (DEVICEINFO *dev,IRDATA_LAN_FLASH *ird,int len,uint32_t ip);
95 int SendASCII (byte *command,byte result[]);
96 int GetRemotelist (byte *data,byte result[]);
97 int GetCommandlist (byte *data,byte result[]);
99 void SwapWordN (word *pnt);
100 void SwapIntN (int32_t *pnt);
102 void DoExecuteASCIICommand (byte command[],SOCKET sockfd,int client)
104 int len,errcnt,sz,res;
105 char result[65536];
107 memset (result,0,sizeof (result));
108 if (!strncmp (command,"GET_HTML_FILELIST",17)) {
109 len = GetHTMLFileList (command+17,result);
111 else if (!strncmp (command,"FLASH_HTML",10)) {
112 len = FlashHTML (command+10,result);
114 else if (!strncmp (command,"snd",3)) {
115 len = SendASCII (command,result);
117 else if (!strncmp (command,"getremotes",10)) {
118 len = GetRemotelist (command,result);
120 else if (!strncmp (command,"getcommands",11)) {
121 len = GetCommandlist (command,result);
124 else {
125 sprintf (result,"Illegal ASCII Command: %s\n",command);
126 log_print (result,LOG_ERROR);
127 return;
130 sprintf (result+2,"%05d",len);
131 result[7] = ' ';
132 log_print (result,LOG_INFO);
134 errcnt = sz = 0;
135 while (sz < len && errcnt < 20) {
136 res = send (sockfd,result + sz,len - sz,MSG_NOSIGNAL);
137 if (res > 0) sz += res;
138 if (res == -1) {
139 msSleep (100);
140 errcnt++;
144 if (res <= 0 && len) {
145 CloseIRSocket (client);
146 sprintf (result,"IP Connection lost\n");
147 log_print (result,LOG_ERROR);
151 int GetCommandlist (byte *data,byte result[])
153 int i,j,res;
154 COMMANDBUFFER cb;
156 i = 12;
158 while (data[i] && data[i] != ',') i++;
159 if (data[i]) data[i++] = 0;
161 res = GetCommandDatabase (&cb,data+12,atoi (data+i));
162 if (res) {
163 sprintf (result,"**00000 RESULT ERROR: Remote %s not found\n",data+12);
164 log_print (result+15, LOG_ERROR);
165 return ((int)strlen (result));
168 sprintf (result,"**00000 COMMANDLIST %d,%d,%d",cb.offset,cb.count_total,cb.count_buffer);
170 for (i=0;i < cb.count_buffer;i++) {
171 strcat (result,",");
172 j = 19;
173 while (j && cb.commands[i][j] == ' ') j--;
174 cb.commands[i][j+1] = 0;
175 strcat (result,cb.commands[i]);
177 strcat (result,"\n");
179 return ((int)strlen (result));
183 int GetRemotelist (byte *data,byte result[])
185 int i,j;
186 REMOTEBUFFER rb;
187 GetRemoteDatabase (&rb,atoi (data + 11));
189 sprintf (result,"**00000 REMOTELIST %d,%d,%d",rb.offset,rb.count_total,rb.count_buffer);
191 for (i=0;i < rb.count_buffer;i++) {
192 strcat (result,",");
193 j = 79;
194 while (j && rb.remotes[i].name[j] == ' ') j--;
195 rb.remotes[i].name[j+1] = 0;
196 strcat (result,rb.remotes[i].name);
198 strcat (result,"\n");
200 return ((int)strlen (result));
204 int SendASCII (byte *data,byte result[])
206 int res;
207 int cmd_num,adr;
208 char err[256],txt[256];
209 char remote[80],command[20],ccf[2048];
210 int netcom,netmask,bus,led,port;
212 res = AnalyzeUDPString (data,&netcom,remote,command,ccf,&netmask,&bus,&led,&port);
213 if (res) {
214 log_print ("Illegal IRTrans ASCII Command\n", LOG_ERROR);
215 strcpy (result,"**00000 RESULT FORMAT ERROR\n");
216 return ((int)strlen (result));
219 sprintf (txt,"IRTrans ASCII Command: %d %s,%s,%d,%d\n", netcom,remote,command,bus,led);
220 log_print (txt,LOG_DEBUG);
222 adr = 0;
224 if (netmask) adr |= 0x10000 | netmask;
225 adr |= (led & 3) << 17;
226 if (bus == 255) adr |= 0x40000000;
227 else adr |= bus << 19;
228 protocol_version = 210;
230 if (netcom == 1) {
231 res = DBFindRemoteCommand (remote,command,&cmd_num,NULL);
232 if (res) {
233 GetError (res, txt);
234 switch(res) {
235 case ERR_REMOTENOTFOUND:
236 sprintf (err, txt, remote);
237 break;
238 case ERR_COMMANDNOTFOUND:
239 sprintf (err, txt, command);
240 break;
241 default:
242 sprintf (err, txt);
243 break;
245 sprintf (result,"**00000 RESULT ERROR: %s",err);
246 log_print (err, LOG_ERROR);
247 return ((int)strlen (result));
249 SendIR (cmd_num,adr);
250 strcpy (result,"**00000 RESULT OK\n");
252 return ((int)strlen (result));
255 // Bus übergeben !!!
257 int FlashHTML (byte *command,byte result[])
259 int i,p,pos;
260 struct stat fst;
261 word flashpage,adr;
262 word cnt = 0;
263 unsigned int mem[65536];
264 char fname[256];
265 HTTP_DIRECTORY *dir;
266 IRDATA_LAN_FLASH ird;
267 FILE *fp;
269 while (*command == ' ') command++;
271 p = 0;
272 cnt = 0;
274 memset (mem,0,sizeof (mem));
275 dir = (HTTP_DIRECTORY *)mem;
276 memset (&ird,0,sizeof (IRDATA_LAN_FLASH));
278 while (command[p]) {
279 i = p;
281 while (command[i] != ';') i++;
282 command[i] = 0;
284 #ifdef WIN32
285 sprintf (fname,"..\\html\\%s",command+p);
286 fp = fopen (fname,"rb");
287 #else
288 sprintf (fname,"../html/%s",command+p);
289 fp = fopen (fname,"r");
290 #endif
291 if (fp) {
292 strncpy (dir->dir[cnt].name,command+p,22);
293 dir->dir[cnt].name[22] = 0;
295 #ifdef WIN32
296 fstat (_fileno(fp),&fst);
297 #else
298 fstat (fileno(fp),&fst);
299 #endif
301 dir->dir[cnt].timestamp = (unsigned int)(fst.st_mtime + ((unsigned int)70 * 365 * 24 * 3600) + ((unsigned int)17 * 24 * 3600)); // Umrechnung auf NTP Format
302 SwapIntN (&dir->dir[cnt].timestamp);
304 if (fst.st_size > 0xffff) dir->dir[cnt].len = 0xffff;
305 else dir->dir[cnt].len = (word)fst.st_size;
307 if (!strcmp (dir->dir[cnt].name + strlen (dir->dir[cnt].name) - 4,".txt")) dir->dir[cnt].filetype = CONTENT_PLAIN | EXTERNAL_FILE;
308 else if (!strcmp (dir->dir[cnt].name + strlen (dir->dir[cnt].name) - 4,".htm")) dir->dir[cnt].filetype = CONTENT_HTML | EXTERNAL_FILE;
309 else if (!strcmp (dir->dir[cnt].name + strlen (dir->dir[cnt].name) - 5,".html")) dir->dir[cnt].filetype = CONTENT_HTML | EXTERNAL_FILE;
310 else if (!strcmp (dir->dir[cnt].name + strlen (dir->dir[cnt].name) - 4,".jpg")) dir->dir[cnt].filetype = CONTENT_JPEG | EXTERNAL_FILE;
311 else if (!strcmp (dir->dir[cnt].name + strlen (dir->dir[cnt].name) - 5,".jpeg")) dir->dir[cnt].filetype = CONTENT_JPEG | EXTERNAL_FILE;
312 else if (!strcmp (dir->dir[cnt].name + strlen (dir->dir[cnt].name) - 4,".gif")) dir->dir[cnt].filetype = CONTENT_GIF | EXTERNAL_FILE;
313 else dir->dir[cnt].filetype = EXTERNAL_FILE;
314 cnt++;
315 fclose (fp);
318 p = i + 1;
321 dir->count = (word)cnt;
322 dir->magic = F_MAGIC;
323 pos = (cnt * sizeof (HTTP_DIRENTRY)) / 4 + 1;
325 for (cnt=0;cnt < dir->count && pos < 32768;cnt++) {
326 #ifdef WIN32
327 sprintf (fname,"..\\html\\%s",dir->dir[cnt].name);
328 fp = fopen (fname,"rb");
329 #else
330 sprintf (fname,"../html/%s",dir->dir[cnt].name);
331 fp = fopen (fname,"r");
332 #endif
333 if (!fp) continue;
335 fread (&mem[pos],1,dir->dir[cnt].len,fp);
336 fclose (fp);
338 dir->dir[cnt].adr = pos;
339 pos += (dir->dir[cnt].len + 3) / 4;
341 SwapWordN (&dir->dir[cnt].adr);
342 SwapWordN (&dir->dir[cnt].len);
344 SwapWordN (&dir->count);
345 SwapWordN (&dir->magic);
347 sprintf (fname,"HTML Size: %d\n",pos * 4);
348 log_print (fname,LOG_INFO);
350 if (pos >= 32768) {
351 sprintf (fname,"HTML Size %d (Max. is 128K)\n",pos * 4);
352 log_print (fname,LOG_ERROR);
353 sprintf (result,"**00000 RESULT_HTML_FLASH E%s\n",fname);
354 return ((int)strlen (result));
357 flashpage = 128;
359 p = adr = 0;
360 while (adr < pos && p != 'E') {
361 i = 0;
362 do {
363 ird.adr = adr;
364 ird.len = flashpage;
366 SwapWordN (&ird.adr);
367 SwapWordN (&ird.len);
369 memcpy (ird.data,mem + adr,flashpage);
370 ird.netcommand = COMMAND_FLASH_HTML;
371 #ifdef WIN32
372 p = IRTransLanFlash (IRDevices,&ird,flashpage,IRDevices[0].io.IPAddr[0].sin_addr.S_un.S_addr);
373 #else
374 p = IRTransLanFlash (IRDevices,&ird,flashpage,IRDevices[0].io.IPAddr[0].sin_addr.s_addr);
375 #endif
376 if (!p) p = 'E';
377 i++;
378 } while (p == 'E' && i < 5);
379 adr += flashpage / 4;
382 if (p == 'E') {
383 strcpy (result,"**00000 RESULT_HTML_FLASH E\n");
385 else {
386 sprintf (result,"**00000 RESULT_HTML_FLASH O%d\n",pos * 4);
388 return ((int)strlen (result));
393 int GetHTMLFileList (byte *command,byte result[])
395 word cnt = 0,len;
396 char fname[256];
397 FILE *fp;
398 struct stat fst;
399 char st[256];
400 struct tm *atime;
402 #ifdef WIN32
403 struct _finddata_t c_file;
404 #ifdef _M_X64
405 intptr_t hFile;
406 #else
407 int hFile;
408 #endif
409 #endif
411 #ifdef LINUX
412 int fd,pos,lend;
413 long off;
414 struct dirent *di;
415 char mem[2048];
416 #endif
418 while (*command == ' ') command++;
420 memcpy (result,"**00000 RESULT_HTML_FILELIST ",29);
421 len = 29;
423 #ifdef WIN32
424 if((hFile = _findfirst( "..\\html\\*.*", &c_file )) != -1L) {
425 do if (c_file.attrib != _A_SUBDIR) {
426 sprintf (fname,"..\\html\\%s",c_file.name);
427 fp = fopen (fname,"r");
428 if (fp) {
429 fstat (_fileno(fp),&fst);
430 strncpy (result+len,c_file.name,22);
431 strcat (result,";");
433 atime = localtime (&fst.st_mtime);
434 sprintf (st,"%d;%02d.%02d.%04d %02d:%02d;",fst.st_size,atime->tm_mday,atime->tm_mon+1,atime->tm_year + 1900,atime->tm_hour,atime->tm_min);
435 strcat (result,st);
437 len = (word)strlen (result);
438 cnt++;
439 fclose (fp);
441 } while( _findnext( hFile, &c_file ) == 0);
442 _findclose( hFile );
444 #endif
446 #ifdef LINUX
447 fd = open ("../html",0);
448 do {
449 lend = getdirentries (fd,mem,2048,&off);
450 pos = 0;
451 while (pos < lend) {
452 di = (struct dirent *)&mem[pos];
454 sprintf (fname,"../html/%s",di->d_name);
455 fp = fopen (fname,"r");
456 if (fp && !fstat (fileno(fp),&fst) && S_ISREG (fst.st_mode)) {
457 strncpy (result+len,di->d_name,22);
458 strcat (result,";");
460 atime = localtime (&fst.st_mtime);
461 sprintf (st,"%d;%02d.%02d.%04d %02d:%02d;",fst.st_size,atime->tm_mday,atime->tm_mon+1,atime->tm_year + 1900,atime->tm_hour,atime->tm_min);
462 strcat (result,st);
464 len = strlen (result);
465 cnt++;
466 fclose (fp);
469 pos += di -> d_reclen;
471 } while (lend);
473 close (fd);
474 #endif
476 strcat (result,"\n");
477 len++;
478 return (len);