Go to the documentation of this file.
23 #include <sys/socket.h>
25 #include <sys/types.h>
70 const char *token,
const char *token2,
char **mode,
75 const char *name,
int line);
84 const char *current_file);
86 const char *
file,
const char *current_file,
105 char *button,
unsigned int rep);
108 char **
string,
char **prog);
112 static int lirc_send_command(
const struct lirc_state *state,
int sockfd,
const char *command,
char *buf,
size_t *buf_len,
int *ret_status);
120 va_start(ap,format_str);
121 vfprintf(
stderr,format_str,ap);
138 struct sockaddr_un addr {};
142 if(lircrc_root_file==
nullptr || lircrc_user_file ==
nullptr || prog==
nullptr)
144 lirc_printf(
nullptr,
"%s: lirc_init invalid params\n",prog);
183 addr.sun_family=AF_UNIX;
184 strncpy(addr.sun_path,lircd,
sizeof(addr.sun_path)-1);
185 state->
lirc_lircd=socket(AF_UNIX,SOCK_STREAM,0);
193 if(connect(state->
lirc_lircd,(
struct sockaddr *)&addr,
sizeof(addr))==-1)
239 char *newline=(
char *) malloc(
LIRC_READ+1);
248 char *ret=fgets(newline+len,
LIRC_READ+1,f);
263 if(newline[len-1]==
'\n')
270 char *enlargeline=(
char *) realloc(newline,len+1+
LIRC_READ);
271 if(enlargeline==
nullptr)
283 while(s[0]==
' ' || s[0]==
'\t') s++;
288 if(s[len]==
' ' || s[len]==
'\t') s[len]=0;
300 unsigned int count = 0;
354 if(i>(1<<CHAR_BIT)-1)
358 "out of range in %s:%d\n",state->
lirc_prog,
373 else if(c>=
'a' && c<=
'f')
375 else if(c>=
'A' && c<=
'F')
382 overflow|=i^(i<<4>>4);
389 "following hex digits in %s:%d\n",
392 if(overflow || i>(1<<CHAR_BIT)-1)
396 "of range in %s:%d\n",
402 if(c>=
'@' && c<=
'Z')
return(c-
'@');
429 [[maybe_unused]]
const char *name,
430 [[maybe_unused]]
int line)
432 size_t len=strlen(s);
438 if(*s!=
'"' && *s!=
'<')
442 if(*s==
'"' && last!=
'"')
446 if(*s==
'<' && last!=
'>')
451 memmove(s, s+1, len-2+1);
455 const char *token,
const char *token2,
char **mode,
459 int (check)(
char *s),
460 const char *name,
int line)
463 if(strcasecmp(token,
"begin")==0)
467 if(new_entry==
nullptr)
471 if(new_entry==
nullptr)
478 new_entry->
prog=
nullptr;
479 new_entry->
code=
nullptr;
482 new_entry->
config=
nullptr;
485 new_entry->
mode=
nullptr;
488 new_entry->
next=
nullptr;
490 *new_config=new_entry;
501 if(new_entry==
nullptr && *
mode==
nullptr)
503 *
mode=strdup(token2);
517 else if(strcasecmp(token,
"end")==0)
521 if(new_entry!=
nullptr)
524 if(new_entry->
prog==
nullptr)
527 "config before line %d\n",
542 if(*last_config==
nullptr)
544 *first_config=new_entry;
545 *last_config=new_entry;
549 (*last_config)->
next=new_entry;
550 *last_config=new_entry;
557 if(new_entry->
mode==
nullptr)
567 new_entry->
prog!=
nullptr &&
573 if(check(list->
string)==-1)
598 if(new_entry!=
nullptr)
605 if(strcasecmp(*mode,token2)==0)
613 "match mode \"%s\"\n",
629 lirc_printf(state,
"%s: unknown token \"%s\" in %s:%d ignored\n",
637 char *strtok_state =
nullptr;
638 unsigned int flags=
none;
639 char *s=strtok_r(
string,
" \t|",&strtok_state);
642 if(strcasecmp(s,
"once")==0)
646 else if(strcasecmp(s,
"quit")==0)
650 else if(strcasecmp(s,
"mode")==0)
654 else if(strcasecmp(s,
"startup_mode")==0)
658 else if(strcasecmp(s,
"toggle_reset")==0)
666 s=strtok_r(
nullptr,
" \t",&strtok_state);
673 const char *current_file)
679 const char *home=getenv(
"HOME");
684 filename=(
char *) malloc(strlen(home)+1+
698 else if(strncmp(
file,
"~/", 2)==0)
700 const char *home=getenv(
"HOME");
714 else if(
file[0]==
'/' || current_file==
nullptr)
727 int pathlen = strlen(current_file);
728 while (pathlen>0 && current_file[pathlen-1]!=
'/')
736 memcpy(
filename,current_file,pathlen);
744 const char *
file,
const char *current_file,
754 if(fin==
nullptr && (
file!=
nullptr || errno!=ENOENT))
756 lirc_printf(state,
"%s: could not open config file %s\n",
760 else if(fin==
nullptr)
763 if(fin==
nullptr && errno!=ENOENT)
765 lirc_printf(state,
"%s: could not open config file %s\n",
769 else if(fin==
nullptr)
771 lirc_printf(state,
"%s: could not open config files "
788 if(full_name && fin!=
nullptr)
802 if (entry ==
nullptr)
807 entry->m_file =
nullptr;
808 entry->m_name =
nullptr;
810 entry->m_parent = parent;
838 int (check)(
char *s))
840 struct sockaddr_un addr {};
842 const char *sha_bang2 =
nullptr;
843 char *command =
nullptr;
844 unsigned int ret = 0;
847 char *sha_bang =
nullptr;
853 if(sha_bang ==
nullptr)
855 goto lirc_readconfig_compat;
860 addr.sun_family=AF_UNIX;
864 goto lirc_readconfig_compat;
866 sockfd=socket(AF_UNIX,SOCK_STREAM,0);
871 goto lirc_readconfig_compat;
873 if(connect(sockfd, (
struct sockaddr *)&addr,
sizeof(addr))!=-1)
875 if(sha_bang!=
nullptr) free(sha_bang);
876 (*config)->sockfd=sockfd;
894 command=
static_cast<char*
>(malloc(strlen(sha_bang2)+1+strlen(
filename)+1));
897 goto lirc_readconfig_compat;
899 strcpy(command, sha_bang2);
900 strcat(command,
" ");
903 ret = system(command);
906 if(ret!=EXIT_SUCCESS)
908 goto lirc_readconfig_compat;
911 if(sha_bang!=
nullptr) { free(sha_bang); sha_bang =
nullptr; }
914 sockfd=socket(AF_UNIX,SOCK_STREAM,0);
919 goto lirc_readconfig_compat;
921 if(connect(sockfd, (
struct sockaddr *)&addr,
sizeof(addr))!=-1)
925 (*config)->sockfd=sockfd;
933 lirc_readconfig_compat:
935 if(sha_bang!=
nullptr) free(sha_bang);
943 int (check)(
char *s))
951 int (check)(
char *s),
957 char *save_full_name =
nullptr;
960 if (filestack ==
nullptr)
965 if (filestack->
m_file ==
nullptr)
980 char *
string =
nullptr;
982 if(ret==-1 ||
string==
nullptr)
984 fclose(filestack->
m_file);
985 if(open_files == 1 && full_name !=
nullptr)
987 save_full_name = filestack->
m_name;
988 filestack->
m_name =
nullptr;
995 if(firstline && sha_bang)
998 if(strncmp(
string,
"#!", 2)==0)
1000 *sha_bang=strdup(
string+2);
1001 if(*sha_bang==
nullptr)
1012 char *eq=strchr(
string,
'=');
1015 char *strtok_state =
nullptr;
1016 char *token=strtok_r(
string,
" \t",&strtok_state);
1017 if ((token==
nullptr) || (token[0]==
'#'))
1021 else if(strcasecmp(token,
"include") == 0)
1026 "included at %s:%d\n",
1034 char *token2 = strtok_r(
nullptr,
"", &strtok_state);
1037 (token2, filestack->
m_name,
1041 if (stack_tmp ==
nullptr)
1052 filestack = stack_tmp;
1064 char *token2=strtok_r(
nullptr,
" \t",&strtok_state);
1065 if(token2!=
nullptr &&
1066 strtok_r(
nullptr,
" \t",&strtok_state)!=
nullptr)
1068 lirc_printf(state,
"%s: unexpected token in line %s:%d\n",
1073 ret=
lirc_mode(state, token,token2,&mode,
1074 &new_entry,&first,&last,
1091 if(new_entry!=
nullptr)
1110 else if(new_entry==
nullptr)
1112 lirc_printf(state,
"%s: bad file format, %s:%d\n",
1118 token2=strdup(token2);
1125 else if(strcasecmp(token,
"prog")==0)
1127 if(new_entry->
prog!=
nullptr) free(new_entry->
prog);
1128 new_entry->
prog=token2;
1130 else if(strcasecmp(token,
"remote")==0)
1135 if(strcasecmp(
"*",token2)==0)
1145 else if(strcasecmp(token,
"button")==0)
1160 if(strcasecmp(
"*",token2)==0)
1167 code->button=token2;
1171 if(new_entry->
code==
nullptr)
1173 new_entry->
code=code;
1192 else if(strcasecmp(token,
"delay")==0)
1194 char *end =
nullptr;
1197 new_entry->
rep_delay=strtoul(token2,&end,0);
1201 || strlen(token2)==0)
1204 " a valid number for "
1210 else if(strcasecmp(token,
"repeat")==0)
1212 char *end =
nullptr;
1215 new_entry->
rep=strtoul(token2,&end,0);
1216 if((new_entry->
rep==UINT_MAX
1219 || strlen(token2)==0)
1222 " a valid number for "
1228 else if(strcasecmp(token,
"config")==0)
1232 if(new_list==
nullptr)
1243 new_list->string=token2;
1244 new_list->next=
nullptr;
1245 if(new_entry->
config==
nullptr)
1247 new_entry->
config=new_list;
1257 else if(strcasecmp(token,
"mode")==0)
1262 else if(strcasecmp(token,
"flags")==0)
1270 lirc_printf(state,
"%s: unknown token \"%s\" in %s:%d ignored\n",
1280 if(new_entry!=
nullptr)
1284 ret=
lirc_mode(state,
"end",
nullptr,&mode,&new_entry,
1285 &first,&last,check,
"",0);
1286 lirc_printf(state,
"%s: warning: end token missing at end "
1299 lirc_printf(state,
"%s: warning: no end token found for mode "
1308 if(*config==
nullptr)
1314 (*config)->first=
first;
1317 (*config)->current_mode=startupmode ? strdup(startupmode):
nullptr;
1318 (*config)->sockfd=-1;
1319 if(full_name !=
nullptr)
1321 *full_name = save_full_name;
1322 save_full_name =
nullptr;
1329 if(sha_bang && *sha_bang!=
nullptr)
1341 free(save_full_name);
1348 char *startupmode=
nullptr;
1352 while(
scan!=
nullptr)
1355 if(
scan->change_mode!=
nullptr) {
1356 startupmode=
scan->change_mode;
1358 scan->change_mode=
nullptr;
1361 lirc_printf(state,
"%s: startup_mode flags requires 'mode ='\n",
1368 if(startupmode==
nullptr) {
1370 while(
scan!=
nullptr)
1381 if(startupmode==
nullptr)
return nullptr;
1383 while(
scan!=
nullptr)
1386 strcasecmp(startupmode,
scan->change_mode)==0)
1392 return(startupmode);
1405 free(
config->current_mode);
1420 while(code!=
nullptr)
1432 while(list!=
nullptr)
1447 if(
config->current_mode==
nullptr)
1452 while(
scan!=
nullptr)
1454 if(
scan->change_mode!=
nullptr)
1456 if(strcasecmp(
scan->change_mode,
config->current_mode)==0)
1463 free(
config->current_mode);
1464 config->current_mode=
nullptr;
1477 if(
scan->change_mode!=
nullptr)
1479 free(
config->current_mode);
1480 config->current_mode=strdup(
scan->change_mode);
1493 if(
scan->next_config!=
nullptr &&
1494 scan->prog!=
nullptr &&
1498 char *s=
scan->next_config->string;
1499 scan->next_config=
scan->next_config->next;
1500 if(
scan->next_config==
nullptr)
1508 char *button,
unsigned int rep)
1511 if(
scan->code==
nullptr)
1513 return static_cast<int>(
rep==0 ||
1520 strcasecmp(
scan->next_code->remote,remote)==0)
1523 strcasecmp(
scan->next_code->button,button)==0)
1527 if(
scan->code->next==
nullptr ||
rep==0)
1529 scan->next_code=
scan->next_code->next;
1530 if(
scan->code->next !=
nullptr)
1536 if(
scan->next_code==
nullptr)
1539 if(
scan->code->next!=
nullptr ||
rep==0 ||
1548 if(
rep!=0)
return(0);
1557 if(codes==
scan->next_code)
return(0);
1560 while(codes!=
scan->next_code->next)
1611 static int warning=1;
1616 fprintf(
stderr,
"%s: warning: lirc_ir2char() is obsolete\n",
1620 if(
lirc_code2char(state,config,code,&
string)==-1)
return nullptr;
1629 char* command =
static_cast<char*
>(malloc((10+strlen(code)+1+1) *
sizeof(
char)));
1630 if (command ==
nullptr)
1632 static std::array<char,LIRC_PACKET_SIZE> s_buf;
1633 size_t buf_len = s_buf.size();
1636 sprintf(command,
"CODE %s\n", code);
1639 s_buf.data(), &buf_len, &success);
1644 *
string = s_buf.data();
1673 char **
string,
char **prog)
1675 unsigned int rep = 0;
1676 char *strtok_state =
nullptr;
1680 if(sscanf(code,
"%*20x %20x %*5000s %*5000s\n",&rep)==1)
1682 char *backup=strdup(code);
1683 if(backup==
nullptr)
return(-1);
1685 strtok_r(backup,
" ",&strtok_state);
1686 strtok_r(
nullptr,
" ",&strtok_state);
1687 char *
button=strtok_r(
nullptr,
" ",&strtok_state);
1688 char *
remote=strtok_r(
nullptr,
"\n",&strtok_state);
1697 int quit_happened=0;
1698 while(
scan!=
nullptr)
1701 if(exec_level > 0 &&
1702 (
scan->mode==
nullptr ||
1703 (
scan->mode!=
nullptr &&
1704 config->current_mode!=
nullptr &&
1705 strcasecmp(
scan->mode,
config->current_mode)==0)) &&
1712 if(s !=
nullptr &&
prog !=
nullptr)
1752 static int warning=1;
1758 fprintf(
stderr,
"%s: warning: lirc_nextir() is obsolete\n",
1763 if(ret==-1)
return nullptr;
1771 static size_t s_endLen=0;
1772 char *end =
nullptr;
1777 state->
lirc_buffer=(
char *) malloc(s_packetSize+1);
1785 while((end=strchr(state->
lirc_buffer,
'\n'))==
nullptr)
1787 if(s_endLen>=s_packetSize)
1790 char *new_buffer=(
char *) realloc(state->
lirc_buffer,s_packetSize+1);
1791 if(new_buffer==
nullptr)
1800 if(len==-1 && errno==EAGAIN)
return(0);
1819 s_endLen=strlen(end);
1825 if(*
code==
nullptr)
return(-1);
1843 static std::array<char,LIRC_PACKET_SIZE> s_buf;
1844 size_t buf_len = s_buf.size();
1848 s_buf.data(), &buf_len, &success);
1853 return s_buf.data();
1859 return config->current_mode;
1866 static std::array<char,LIRC_PACKET_SIZE> s_buf {};
1867 std::array<char,LIRC_PACKET_SIZE> cmd {};
1868 size_t buf_len = s_buf.size();
1879 s_buf.data(), &buf_len, &success);
1884 return s_buf.data();
1891 free(
config->current_mode);
1893 return config->current_mode;
1898 static std::array<char,LIRC_PACKET_SIZE+1> s_buffer;
1899 char *end =
nullptr;
1900 static size_t s_head=0;
1901 static size_t s_tail=0;
1905 struct timeval tv {};
1909 memmove(s_buffer.data(),s_buffer.data()+s_head,s_tail-s_head+1);
1912 end=strchr(s_buffer.data(),
'\n');
1918 if(strlen(s_buffer.data())!=s_tail)
1921 goto lirc_read_string_error;
1929 goto lirc_read_string_error;
1938 ret=select(fd+1,&fds,
nullptr,
nullptr,&tv);
1940 while(ret==-1 && errno==EINTR);
1945 goto lirc_read_string_error;
1950 goto lirc_read_string_error;
1958 goto lirc_read_string_error;
1960 s_buffer[s_tail+n]=0;
1962 end=strchr(s_buffer.data(),
'\n');
1966 s_head=strlen(s_buffer.data())+1;
1967 return(s_buffer.data());
1969 lirc_read_string_error:
1977 char *endptr =
nullptr;
1978 unsigned long n = 0;
1979 unsigned long data_n=0;
1984 if(buf_len!=
nullptr)
1988 int todo=strlen(command);
1989 const char *data=command;
1992 int done=
write(sockfd,(
const void *) data,todo);
1995 lirc_printf(lstate,
"%s: could not send packet\n",
2011 if(
string==
nullptr)
return(-1);
2015 if(strcasecmp(
string,
"BEGIN")!=0)
2022 if(strncasecmp(
string,command,strlen(
string))!=0 ||
2023 strlen(
string)+1!=strlen(command))
2031 if(strcasecmp(
string,
"SUCCESS")==0)
2035 else if(strcasecmp(
string,
"END")==0)
2040 else if(strcasecmp(
string,
"ERROR")==0)
2053 if(strcasecmp(
string,
"END")==0)
2057 else if(strcasecmp(
string,
"DATA")==0)
2065 data_n=strtoul(
string,&endptr,0);
2066 if(!*
string || *endptr)
2081 if(buf!=
nullptr && written+len+1<max)
2083 memcpy(buf+written,
string, len+1);
2087 if(n==data_n) state=
P_END;
2090 if(strcasecmp(
string,
"END")==0)
2106 if(ret_status!=
nullptr)
2110 if(buf_len!=
nullptr)
2114 return (
int) data_n;
2119 char* command =
static_cast<char*
>(malloc((10+strlen(state->
lirc_prog)+1+1) *
sizeof(
char)));
2120 if (command ==
nullptr)
2124 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)