Go to the documentation of this file.
27 #include <sys/socket.h>
29 #include <sys/types.h>
74 const char *token,
const char *token2,
char **mode,
79 const char *name,
int line);
88 const char *current_file);
90 const char *
file,
const char *current_file,
109 char *button,
unsigned int rep);
112 char **
string,
char **prog);
116 static int lirc_send_command(
const struct lirc_state *state,
int sockfd,
const char *command,
char *buf,
size_t *buf_len,
int *ret_status);
124 va_start(ap,format_str);
125 vfprintf(
stderr,format_str,ap);
142 struct sockaddr_un addr {};
146 if(lircrc_root_file==
nullptr || lircrc_user_file ==
nullptr || prog==
nullptr)
148 lirc_printf(
nullptr,
"%s: lirc_init invalid params\n",prog);
187 addr.sun_family=AF_UNIX;
188 strncpy(addr.sun_path,lircd,
sizeof(addr.sun_path)-1);
189 state->
lirc_lircd=socket(AF_UNIX,SOCK_STREAM,0);
197 if(connect(state->
lirc_lircd,(
struct sockaddr *)&addr,
sizeof(addr))==-1)
243 char *newline=(
char *) malloc(
LIRC_READ+1);
252 char *ret=fgets(newline+len,
LIRC_READ+1,f);
267 if(newline[len-1]==
'\n')
274 char *enlargeline=(
char *) realloc(newline,len+1+
LIRC_READ);
275 if(enlargeline==
nullptr)
287 while(s[0]==
' ' || s[0]==
'\t') s++;
292 if(s[len]==
' ' || s[len]==
'\t') s[len]=0;
304 unsigned int count = 0;
358 if(i>(1<<CHAR_BIT)-1)
362 "out of range in %s:%d\n",state->
lirc_prog,
377 else if(c>=
'a' && c<=
'f')
379 else if(c>=
'A' && c<=
'F')
386 overflow|=i^(i<<4>>4);
393 "following hex digits in %s:%d\n",
396 if(overflow || i>(1<<CHAR_BIT)-1)
400 "of range in %s:%d\n",
406 if(c>=
'@' && c<=
'Z')
return(c-
'@');
436 size_t len=strlen(s);
442 if(*s!=
'"' && *s!=
'<')
446 if(*s==
'"' && last!=
'"')
450 if(*s==
'<' && last!=
'>')
455 memmove(s, s+1, len-2+1);
459 const char *token,
const char *token2,
char **mode,
463 int (check)(
char *s),
464 const char *name,
int line)
467 if(strcasecmp(token,
"begin")==0)
471 if(new_entry==
nullptr)
475 if(new_entry==
nullptr)
482 new_entry->
prog=
nullptr;
483 new_entry->
code=
nullptr;
486 new_entry->
config=
nullptr;
489 new_entry->
mode=
nullptr;
492 new_entry->
next=
nullptr;
494 *new_config=new_entry;
505 if(new_entry==
nullptr && *
mode==
nullptr)
507 *
mode=strdup(token2);
521 else if(strcasecmp(token,
"end")==0)
525 if(new_entry!=
nullptr)
528 if(new_entry->
prog==
nullptr)
531 "config before line %d\n",
546 if(*last_config==
nullptr)
548 *first_config=new_entry;
549 *last_config=new_entry;
553 (*last_config)->
next=new_entry;
554 *last_config=new_entry;
561 if(new_entry->
mode==
nullptr)
571 new_entry->
prog!=
nullptr &&
577 if(check(list->
string)==-1)
602 if(new_entry!=
nullptr)
609 if(strcasecmp(*mode,token2)==0)
617 "match mode \"%s\"\n",
633 lirc_printf(state,
"%s: unknown token \"%s\" in %s:%d ignored\n",
641 char *strtok_state =
nullptr;
642 unsigned int flags=
none;
643 char *s=strtok_r(
string,
" \t|",&strtok_state);
646 if(strcasecmp(s,
"once")==0)
650 else if(strcasecmp(s,
"quit")==0)
654 else if(strcasecmp(s,
"mode")==0)
658 else if(strcasecmp(s,
"startup_mode")==0)
662 else if(strcasecmp(s,
"toggle_reset")==0)
670 s=strtok_r(
nullptr,
" \t",&strtok_state);
677 const char *current_file)
683 const char *home=getenv(
"HOME");
688 filename=(
char *) malloc(strlen(home)+1+
702 else if(strncmp(
file,
"~/", 2)==0)
704 const char *home=getenv(
"HOME");
718 else if(
file[0]==
'/' || current_file==
nullptr)
731 int pathlen = strlen(current_file);
732 while (pathlen>0 && current_file[pathlen-1]!=
'/')
740 memcpy(
filename,current_file,pathlen);
748 const char *
file,
const char *current_file,
758 if(fin==
nullptr && (
file!=
nullptr || errno!=ENOENT))
760 lirc_printf(state,
"%s: could not open config file %s\n",
764 else if(fin==
nullptr)
767 if(fin==
nullptr && errno!=ENOENT)
769 lirc_printf(state,
"%s: could not open config file %s\n",
773 else if(fin==
nullptr)
775 lirc_printf(state,
"%s: could not open config files "
792 if(full_name && fin!=
nullptr)
806 if (entry ==
nullptr)
811 entry->m_file =
nullptr;
812 entry->m_name =
nullptr;
814 entry->m_parent = parent;
842 int (check)(
char *s))
844 struct sockaddr_un addr {};
846 const char *sha_bang2 =
nullptr;
847 char *command =
nullptr;
848 unsigned int ret = 0;
851 char *sha_bang =
nullptr;
857 if(sha_bang ==
nullptr)
859 goto lirc_readconfig_compat;
864 addr.sun_family=AF_UNIX;
868 goto lirc_readconfig_compat;
870 sockfd=socket(AF_UNIX,SOCK_STREAM,0);
875 goto lirc_readconfig_compat;
877 if(connect(sockfd, (
struct sockaddr *)&addr,
sizeof(addr))!=-1)
879 if(sha_bang!=
nullptr) free(sha_bang);
880 (*config)->sockfd=sockfd;
898 command=
static_cast<char*
>(malloc(strlen(sha_bang2)+1+strlen(
filename)+1));
901 goto lirc_readconfig_compat;
903 strcpy(command, sha_bang2);
904 strcat(command,
" ");
907 ret = system(command);
910 if(ret!=EXIT_SUCCESS)
912 goto lirc_readconfig_compat;
915 if(sha_bang!=
nullptr) { free(sha_bang); sha_bang =
nullptr; }
918 sockfd=socket(AF_UNIX,SOCK_STREAM,0);
923 goto lirc_readconfig_compat;
925 if(connect(sockfd, (
struct sockaddr *)&addr,
sizeof(addr))!=-1)
929 (*config)->sockfd=sockfd;
937 lirc_readconfig_compat:
939 if(sha_bang!=
nullptr) free(sha_bang);
947 int (check)(
char *s))
955 int (check)(
char *s),
961 char *save_full_name =
nullptr;
964 if (filestack ==
nullptr)
969 if (filestack->
m_file ==
nullptr)
984 char *
string =
nullptr;
988 fclose(filestack->
m_file);
989 if(open_files == 1 && full_name !=
nullptr)
991 save_full_name = filestack->
m_name;
992 filestack->
m_name =
nullptr;
999 if(firstline && sha_bang)
1002 if(strncmp(
string,
"#!", 2)==0)
1004 *sha_bang=strdup(
string+2);
1005 if(*sha_bang==
nullptr)
1016 char *eq=strchr(
string,
'=');
1019 char *strtok_state =
nullptr;
1020 char *token=strtok_r(
string,
" \t",&strtok_state);
1021 if ((token==
nullptr) || (token[0]==
'#'))
1025 else if(strcasecmp(token,
"include") == 0)
1030 "included at %s:%d\n",
1038 char *token2 = strtok_r(
nullptr,
"", &strtok_state);
1041 (token2, filestack->
m_name,
1045 if (stack_tmp ==
nullptr)
1056 filestack = stack_tmp;
1068 char *token2=strtok_r(
nullptr,
" \t",&strtok_state);
1069 if(token2!=
nullptr &&
1070 strtok_r(
nullptr,
" \t",&strtok_state)!=
nullptr)
1072 lirc_printf(state,
"%s: unexpected token in line %s:%d\n",
1077 ret=
lirc_mode(state, token,token2,&mode,
1078 &new_entry,&first,&last,
1095 if(new_entry!=
nullptr)
1114 else if(new_entry==
nullptr)
1116 lirc_printf(state,
"%s: bad file format, %s:%d\n",
1122 token2=strdup(token2);
1129 else if(strcasecmp(token,
"prog")==0)
1131 if(new_entry->
prog!=
nullptr) free(new_entry->
prog);
1132 new_entry->
prog=token2;
1134 else if(strcasecmp(token,
"remote")==0)
1139 if(strcasecmp(
"*",token2)==0)
1149 else if(strcasecmp(token,
"button")==0)
1164 if(strcasecmp(
"*",token2)==0)
1171 code->button=token2;
1175 if(new_entry->
code==
nullptr)
1177 new_entry->
code=code;
1196 else if(strcasecmp(token,
"delay")==0)
1198 char *end =
nullptr;
1201 new_entry->
rep_delay=strtoul(token2,&end,0);
1205 || strlen(token2)==0)
1208 " a valid number for "
1214 else if(strcasecmp(token,
"repeat")==0)
1216 char *end =
nullptr;
1219 new_entry->
rep=strtoul(token2,&end,0);
1220 if((new_entry->
rep==UINT_MAX
1223 || strlen(token2)==0)
1226 " a valid number for "
1232 else if(strcasecmp(token,
"config")==0)
1236 if(new_list==
nullptr)
1247 new_list->string=token2;
1248 new_list->next=
nullptr;
1249 if(new_entry->
config==
nullptr)
1251 new_entry->
config=new_list;
1261 else if(strcasecmp(token,
"mode")==0)
1266 else if(strcasecmp(token,
"flags")==0)
1274 lirc_printf(state,
"%s: unknown token \"%s\" in %s:%d ignored\n",
1284 if(new_entry!=
nullptr)
1288 ret=
lirc_mode(state,
"end",
nullptr,&mode,&new_entry,
1289 &first,&last,check,
"",0);
1290 lirc_printf(state,
"%s: warning: end token missing at end "
1303 lirc_printf(state,
"%s: warning: no end token found for mode "
1312 if(*config==
nullptr)
1318 (*config)->first=
first;
1321 (*config)->current_mode=startupmode ? strdup(startupmode):
nullptr;
1322 (*config)->sockfd=-1;
1323 if(full_name !=
nullptr)
1325 *full_name = save_full_name;
1326 save_full_name =
nullptr;
1333 if(sha_bang && *sha_bang!=
nullptr)
1345 free(save_full_name);
1352 char *startupmode=
nullptr;
1356 while(
scan!=
nullptr)
1359 if(
scan->change_mode!=
nullptr) {
1360 startupmode=
scan->change_mode;
1362 scan->change_mode=
nullptr;
1365 lirc_printf(state,
"%s: startup_mode flags requires 'mode ='\n",
1372 if(startupmode==
nullptr) {
1374 while(
scan!=
nullptr)
1385 if(startupmode==
nullptr)
return nullptr;
1387 while(
scan!=
nullptr)
1390 strcasecmp(startupmode,
scan->change_mode)==0)
1396 return(startupmode);
1409 free(
config->current_mode);
1424 while(code!=
nullptr)
1436 while(list!=
nullptr)
1451 if(
config->current_mode==
nullptr)
1456 while(
scan!=
nullptr)
1458 if(
scan->change_mode!=
nullptr)
1460 if(strcasecmp(
scan->change_mode,
config->current_mode)==0)
1467 free(
config->current_mode);
1468 config->current_mode=
nullptr;
1481 if(
scan->change_mode!=
nullptr)
1483 free(
config->current_mode);
1484 config->current_mode=strdup(
scan->change_mode);
1497 if(
scan->next_config!=
nullptr &&
1498 scan->prog!=
nullptr &&
1502 char *s=
scan->next_config->string;
1503 scan->next_config=
scan->next_config->next;
1504 if(
scan->next_config==
nullptr)
1512 char *button,
unsigned int rep)
1515 if(
scan->code==
nullptr)
1517 return static_cast<int>(
rep==0 ||
1524 strcasecmp(
scan->next_code->remote,remote)==0)
1527 strcasecmp(
scan->next_code->button,button)==0)
1531 if(
scan->code->next==
nullptr ||
rep==0)
1533 scan->next_code=
scan->next_code->next;
1534 if(
scan->code->next !=
nullptr)
1540 if(
scan->next_code==
nullptr)
1543 if(
scan->code->next!=
nullptr ||
rep==0 ||
1552 if(
rep!=0)
return(0);
1561 if(codes==
scan->next_code)
return(0);
1564 while(codes!=
scan->next_code->next)
1615 static int warning=1;
1620 fprintf(
stderr,
"%s: warning: lirc_ir2char() is obsolete\n",
1624 if(
lirc_code2char(state,config,code,&
string)==-1)
return nullptr;
1633 char* command =
static_cast<char*
>(malloc((10+strlen(code)+1+1) *
sizeof(
char)));
1634 if (command ==
nullptr)
1636 static std::array<char,LIRC_PACKET_SIZE> s_buf;
1637 size_t buf_len = s_buf.size();
1640 sprintf(command,
"CODE %s\n", code);
1643 s_buf.data(), &buf_len, &success);
1648 *
string = s_buf.data();
1677 char **
string,
char **prog)
1679 unsigned int rep = 0;
1680 char *strtok_state =
nullptr;
1684 if(sscanf(code,
"%*20x %20x %*5000s %*5000s\n",&rep)==1)
1686 char *backup=strdup(code);
1687 if(backup==
nullptr)
return(-1);
1689 strtok_r(backup,
" ",&strtok_state);
1690 strtok_r(
nullptr,
" ",&strtok_state);
1691 char *
button=strtok_r(
nullptr,
" ",&strtok_state);
1692 char *
remote=strtok_r(
nullptr,
"\n",&strtok_state);
1701 int quit_happened=0;
1702 while(
scan!=
nullptr)
1705 if(exec_level > 0 &&
1706 (
scan->mode==
nullptr ||
1707 (
scan->mode!=
nullptr &&
1708 config->current_mode!=
nullptr &&
1709 strcasecmp(
scan->mode,
config->current_mode)==0)) &&
1716 if(s !=
nullptr &&
prog !=
nullptr)
1756 static int warning=1;
1762 fprintf(
stderr,
"%s: warning: lirc_nextir() is obsolete\n",
1767 if(ret==-1)
return nullptr;
1775 static size_t s_endLen=0;
1776 char *end =
nullptr;
1781 state->
lirc_buffer=(
char *) malloc(s_packetSize+1);
1789 while((end=strchr(state->
lirc_buffer,
'\n'))==
nullptr)
1791 if(s_endLen>=s_packetSize)
1794 char *new_buffer=(
char *) realloc(state->
lirc_buffer,s_packetSize+1);
1795 if(new_buffer==
nullptr)
1804 if(len==-1 && errno==EAGAIN)
return(0);
1823 s_endLen=strlen(end);
1829 if(*
code==
nullptr)
return(-1);
1847 static std::array<char,LIRC_PACKET_SIZE> s_buf;
1848 size_t buf_len = s_buf.size();
1852 s_buf.data(), &buf_len, &success);
1857 return s_buf.data();
1863 return config->current_mode;
1870 static std::array<char,LIRC_PACKET_SIZE> s_buf {};
1871 std::array<char,LIRC_PACKET_SIZE> cmd {};
1872 size_t buf_len = s_buf.size();
1883 s_buf.data(), &buf_len, &success);
1888 return s_buf.data();
1895 free(
config->current_mode);
1897 return config->current_mode;
1902 static std::array<char,LIRC_PACKET_SIZE+1> s_buffer;
1903 char *end =
nullptr;
1904 static size_t s_head=0;
1905 static size_t s_tail=0;
1909 struct timeval tv {};
1913 memmove(s_buffer.data(),s_buffer.data()+s_head,s_tail-s_head+1);
1916 end=strchr(s_buffer.data(),
'\n');
1922 if(strlen(s_buffer.data())!=s_tail)
1925 goto lirc_read_string_error;
1933 goto lirc_read_string_error;
1942 ret=select(fd+1,&fds,
nullptr,
nullptr,&tv);
1944 while(ret==-1 && errno==EINTR);
1949 goto lirc_read_string_error;
1954 goto lirc_read_string_error;
1962 goto lirc_read_string_error;
1964 s_buffer[s_tail+n]=0;
1966 end=strchr(s_buffer.data(),
'\n');
1970 s_head=strlen(s_buffer.data())+1;
1971 return(s_buffer.data());
1973 lirc_read_string_error:
1981 char *endptr =
nullptr;
1982 unsigned long n = 0;
1983 unsigned long data_n=0;
1988 if(buf_len!=
nullptr)
1992 int todo=strlen(command);
1993 const char *data=command;
1996 int done=
write(sockfd,(
const void *) data,todo);
1999 lirc_printf(lstate,
"%s: could not send packet\n",
2015 if(
string==
nullptr)
return(-1);
2019 if(strcasecmp(
string,
"BEGIN")!=0)
2026 if(strncasecmp(
string,command,strlen(
string))!=0 ||
2027 strlen(
string)+1!=strlen(command))
2035 if(strcasecmp(
string,
"SUCCESS")==0)
2039 else if(strcasecmp(
string,
"END")==0)
2044 else if(strcasecmp(
string,
"ERROR")==0)
2057 if(strcasecmp(
string,
"END")==0)
2061 else if(strcasecmp(
string,
"DATA")==0)
2069 data_n=strtoul(
string,&endptr,0);
2070 if(!*
string || *endptr)
2085 if(buf!=
nullptr && written+len+1<max)
2087 memcpy(buf+written,
string, len+1);
2091 if(n==data_n) state=
P_END;
2094 if(strcasecmp(
string,
"END")==0)
2110 if(ret_status!=
nullptr)
2114 if(buf_len!=
nullptr)
2118 return (
int) data_n;
2123 char* command =
static_cast<char*
>(malloc((10+strlen(state->
lirc_prog)+1+1) *
sizeof(
char)));
2124 if (command ==
nullptr)
2128 sprintf(command,
"IDENT %s\n", state->
lirc_prog);
static constexpr int8_t LIRC_TIMEOUT
int lirc_readconfig_only(const struct lirc_state *state, const char *file, struct lirc_config **config, int(check)(char *s))
static char * lirc_execute(const struct lirc_state *state, struct lirc_config *config, struct lirc_config_entry *scan)
static const char * lirc_read_string(const struct lirc_state *state, int fd)
static void lirc_parse_string(const struct lirc_state *state, char *s, const char *name, int line)
int lirc_deinit(struct lirc_state *state)
static void lirc_parse_include(char *s, const char *name, int line)
def read(device=None, features=[])
def write(text, progress=True)
static unsigned int lirc_flags(const struct lirc_state *state, char *string)
static int lirc_send_command(const struct lirc_state *state, int sockfd, const char *command, char *buf, size_t *buf_len, int *ret_status)
static int lirc_mode(const struct lirc_state *state, const char *token, const char *token2, char **mode, struct lirc_config_entry **new_config, struct lirc_config_entry **first_config, struct lirc_config_entry **last_config, int(check)(char *s), const char *name, int line)
static int lirc_identify(const struct lirc_state *state, int sockfd)
static void lirc_freeconfigentries(struct lirc_config_entry *first)
static void lirc_perror(const struct lirc_state *, const char *s)
static void lirc_printf(const struct lirc_state *, const char *format_str,...)
def scan(profile, smoonURL, gate)
const char * lirc_setmode(const struct lirc_state *state, struct lirc_config *config, const char *mode)
static FILE * lirc_open(const struct lirc_state *state, const char *file, const char *current_file, char **full_name)
struct lirc_state * lirc_init(const char *lircrc_root_file, const char *lircrc_user_file, const char *prog, const char *lircd, int verbose)
void lirc_freeconfig(struct lirc_config *config)
static int lirc_readline(const struct lirc_state *state, char **line, FILE *f)
int lirc_code2charprog(struct lirc_state *state, struct lirc_config *config, char *code, char **string, char **prog)
int lirc_code2char(const struct lirc_state *state, struct lirc_config *config, const char *code, char **string)
struct lirc_config_entry * first
static struct filestack_t * stack_pop(struct filestack_t *entry)
static int lirc_readconfig_only_internal(const struct lirc_state *state, const char *file, struct lirc_config **config, int(check)(char *s), char **full_name, char **sha_bang)
size_t lirc_getsocketname(const char *filename, char *buf, size_t size)
static char * lirc_trim(char *s)
static char * lirc_startupmode(const struct lirc_state *state, struct lirc_config_entry *first)
static constexpr int8_t MAX_INCLUDES
static char * lirc_getfilename(const struct lirc_state *state, const char *file, const char *current_file)
struct lirc_list * next_config
static void lirc_clearmode(struct lirc_config *config)
static int lirc_iscode(struct lirc_config_entry *scan, char *remote, char *button, unsigned int rep)
struct filestack_t * m_parent
static constexpr size_t LIRC_PACKET_SIZE
int lirc_readconfig(const struct lirc_state *state, const char *file, struct lirc_config **config, int(check)(char *s))
static char lirc_parse_escape(const struct lirc_state *state, char **s, const char *name, int line)
static int lirc_code2char_internal(const struct lirc_state *state, struct lirc_config *config, const char *code, char **string, char **prog)
static constexpr size_t PACKET_SIZE
int lirc_nextcode(struct lirc_state *state, char **code)
struct lirc_config_entry * next
static void stack_free(struct filestack_t *entry)
static constexpr size_t LIRC_READ
static struct filestack_t * stack_push(const struct lirc_state *state, struct filestack_t *parent)
struct lirc_list * config
struct lirc_code * next_code
const char * lirc_getmode(const struct lirc_state *state, struct lirc_config *config)