Go to the documentation of this file.
25 #include <sys/socket.h>
27 #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,
99 std::string& full_name,
100 std::string& sha_bang);
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-
'@');
433 [[maybe_unused]]
const char *name,
434 [[maybe_unused]]
int line)
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 unsigned int ret = 0;
849 std::string sha_bang;
860 addr.sun_family=AF_UNIX;
866 sockfd=socket(AF_UNIX,SOCK_STREAM,0);
873 if(connect(sockfd, (
struct sockaddr *)&addr,
sizeof(addr))!=-1)
875 (*config)->sockfd=sockfd;
890 std::string command = sha_bang +
" " +
filename;
891 ret = system(command.data());
893 if(ret!=EXIT_SUCCESS)
896 sockfd=socket(AF_UNIX,SOCK_STREAM,0);
903 if(connect(sockfd, (
struct sockaddr *)&addr,
sizeof(addr))!=-1)
907 (*config)->sockfd=sockfd;
919 int (check)(
char *s))
922 std::string sha_bang;
929 int (check)(
char *s),
930 std::string& full_name,
931 std::string& sha_bang)
937 if (filestack ==
nullptr)
942 if (filestack->
m_file ==
nullptr)
957 char *
string =
nullptr;
959 if(ret==-1 ||
string==
nullptr)
961 fclose(filestack->
m_file);
964 full_name = filestack->
m_name;
974 if(strncmp(
string,
"#!", 2)==0)
980 char *eq=strchr(
string,
'=');
983 char *strtok_state =
nullptr;
984 char *token=strtok_r(
string,
" \t",&strtok_state);
985 if ((token==
nullptr) || (token[0]==
'#'))
989 else if(strcasecmp(token,
"include") == 0)
994 "included at %s:%d\n",
1002 char *token2 = strtok_r(
nullptr,
"", &strtok_state);
1005 (token2, filestack->
m_name,
1009 if (stack_tmp ==
nullptr)
1020 filestack = stack_tmp;
1032 char *token2=strtok_r(
nullptr,
" \t",&strtok_state);
1033 if(token2!=
nullptr &&
1034 strtok_r(
nullptr,
" \t",&strtok_state)!=
nullptr)
1036 lirc_printf(state,
"%s: unexpected token in line %s:%d\n",
1041 ret=
lirc_mode(state, token,token2,&mode,
1042 &new_entry,&first,&last,
1059 if(new_entry!=
nullptr)
1078 else if(new_entry==
nullptr)
1080 lirc_printf(state,
"%s: bad file format, %s:%d\n",
1086 token2=strdup(token2);
1093 else if(strcasecmp(token,
"prog")==0)
1095 if(new_entry->
prog!=
nullptr) free(new_entry->
prog);
1096 new_entry->
prog=token2;
1098 else if(strcasecmp(token,
"remote")==0)
1103 if(strcasecmp(
"*",token2)==0)
1113 else if(strcasecmp(token,
"button")==0)
1128 if(strcasecmp(
"*",token2)==0)
1135 code->button=token2;
1139 if(new_entry->
code==
nullptr)
1141 new_entry->
code=code;
1160 else if(strcasecmp(token,
"delay")==0)
1162 char *end =
nullptr;
1165 new_entry->
rep_delay=strtoul(token2,&end,0);
1169 || strlen(token2)==0)
1172 " a valid number for "
1178 else if(strcasecmp(token,
"repeat")==0)
1180 char *end =
nullptr;
1183 new_entry->
rep=strtoul(token2,&end,0);
1184 if((new_entry->
rep==UINT_MAX
1187 || strlen(token2)==0)
1190 " a valid number for "
1196 else if(strcasecmp(token,
"config")==0)
1200 if(new_list==
nullptr)
1211 new_list->string=token2;
1212 new_list->next=
nullptr;
1213 if(new_entry->
config==
nullptr)
1215 new_entry->
config=new_list;
1225 else if(strcasecmp(token,
"mode")==0)
1230 else if(strcasecmp(token,
"flags")==0)
1238 lirc_printf(state,
"%s: unknown token \"%s\" in %s:%d ignored\n",
1248 if(new_entry!=
nullptr)
1252 ret=
lirc_mode(state,
"end",
nullptr,&mode,&new_entry,
1253 &first,&last,check,
"",0);
1254 lirc_printf(state,
"%s: warning: end token missing at end "
1267 lirc_printf(state,
"%s: warning: no end token found for mode "
1276 if(*config==
nullptr)
1282 (*config)->first=
first;
1285 (*config)->current_mode=startupmode ? strdup(startupmode):
nullptr;
1286 (*config)->sockfd=-1;
1303 char *startupmode=
nullptr;
1307 while(
scan!=
nullptr)
1310 if(
scan->change_mode!=
nullptr) {
1311 startupmode=
scan->change_mode;
1313 scan->change_mode=
nullptr;
1316 lirc_printf(state,
"%s: startup_mode flags requires 'mode ='\n",
1323 if(startupmode==
nullptr) {
1325 while(
scan!=
nullptr)
1336 if(startupmode==
nullptr)
return nullptr;
1338 while(
scan!=
nullptr)
1341 strcasecmp(startupmode,
scan->change_mode)==0)
1347 return(startupmode);
1360 free(
config->current_mode);
1375 while(code!=
nullptr)
1387 while(list!=
nullptr)
1402 if(
config->current_mode==
nullptr)
1407 while(
scan!=
nullptr)
1409 if(
scan->change_mode!=
nullptr)
1411 if(strcasecmp(
scan->change_mode,
config->current_mode)==0)
1418 free(
config->current_mode);
1419 config->current_mode=
nullptr;
1432 if(
scan->change_mode!=
nullptr)
1434 free(
config->current_mode);
1435 config->current_mode=strdup(
scan->change_mode);
1448 if(
scan->next_config!=
nullptr &&
1449 scan->prog!=
nullptr &&
1453 char *s=
scan->next_config->string;
1454 scan->next_config=
scan->next_config->next;
1455 if(
scan->next_config==
nullptr)
1463 char *button,
unsigned int rep)
1466 if(
scan->code==
nullptr)
1468 return static_cast<int>(
rep==0 ||
1475 strcasecmp(
scan->next_code->remote,remote)==0)
1478 strcasecmp(
scan->next_code->button,button)==0)
1482 if(
scan->code->next==
nullptr ||
rep==0)
1484 scan->next_code=
scan->next_code->next;
1485 if(
scan->code->next !=
nullptr)
1491 if(
scan->next_code==
nullptr)
1494 if(
scan->code->next!=
nullptr ||
rep==0 ||
1503 if(
rep!=0)
return(0);
1512 if(codes==
scan->next_code)
return(0);
1515 while(codes!=
scan->next_code->next)
1566 static int warning=1;
1571 fprintf(
stderr,
"%s: warning: lirc_ir2char() is obsolete\n",
1575 if(
lirc_code2char(state,config,code,&
string)==-1)
return nullptr;
1584 char* command =
static_cast<char*
>(malloc((10+strlen(code)+1+1) *
sizeof(
char)));
1585 if (command ==
nullptr)
1587 static std::array<char,LIRC_PACKET_SIZE> s_buf;
1588 size_t buf_len = s_buf.size();
1591 sprintf(command,
"CODE %s\n", code);
1594 s_buf.data(), &buf_len, &success);
1599 *
string = s_buf.data();
1628 char **
string,
char **prog)
1630 unsigned int rep = 0;
1631 char *strtok_state =
nullptr;
1635 if(sscanf(code,
"%*20x %20x %*5000s %*5000s\n",&rep)==1)
1637 char *backup=strdup(code);
1638 if(backup==
nullptr)
return(-1);
1640 strtok_r(backup,
" ",&strtok_state);
1641 strtok_r(
nullptr,
" ",&strtok_state);
1642 char *
button=strtok_r(
nullptr,
" ",&strtok_state);
1643 char *
remote=strtok_r(
nullptr,
"\n",&strtok_state);
1652 int quit_happened=0;
1653 while(
scan!=
nullptr)
1656 if(exec_level > 0 &&
1657 (
scan->mode==
nullptr ||
1658 (
scan->mode!=
nullptr &&
1659 config->current_mode!=
nullptr &&
1660 strcasecmp(
scan->mode,
config->current_mode)==0)) &&
1667 if(s !=
nullptr &&
prog !=
nullptr)
1707 static int warning=1;
1713 fprintf(
stderr,
"%s: warning: lirc_nextir() is obsolete\n",
1718 if(ret==-1)
return nullptr;
1726 static size_t s_endLen=0;
1727 char *end =
nullptr;
1732 state->
lirc_buffer=(
char *) malloc(s_packetSize+1);
1740 while((end=strchr(state->
lirc_buffer,
'\n'))==
nullptr)
1742 if(s_endLen>=s_packetSize)
1745 char *new_buffer=(
char *) realloc(state->
lirc_buffer,s_packetSize+1);
1746 if(new_buffer==
nullptr)
1755 if(len==-1 && errno==EAGAIN)
return(0);
1774 s_endLen=strlen(end);
1780 if(*
code==
nullptr)
return(-1);
1798 static std::array<char,LIRC_PACKET_SIZE> s_buf;
1799 size_t buf_len = s_buf.size();
1803 s_buf.data(), &buf_len, &success);
1808 return s_buf.data();
1814 return config->current_mode;
1821 static std::array<char,LIRC_PACKET_SIZE> s_buf {};
1822 std::array<char,LIRC_PACKET_SIZE> cmd {};
1823 size_t buf_len = s_buf.size();
1834 s_buf.data(), &buf_len, &success);
1839 return s_buf.data();
1846 free(
config->current_mode);
1848 return config->current_mode;
1853 static std::array<char,LIRC_PACKET_SIZE+1> s_buffer;
1854 char *end =
nullptr;
1855 static size_t s_head=0;
1856 static size_t s_tail=0;
1860 struct timeval tv {};
1862 auto cleanup_fn = [&](
int *) {
1866 std::unique_ptr<int,decltype(cleanup_fn)>
cleanup { &ret, cleanup_fn };
1870 memmove(s_buffer.data(),s_buffer.data()+s_head,s_tail-s_head+1);
1873 end=strchr(s_buffer.data(),
'\n');
1879 if(strlen(s_buffer.data())!=s_tail)
1897 ret=select(fd+1,&fds,
nullptr,
nullptr,&tv);
1898 while(ret==-1 && errno==EINTR)
1899 ret=select(fd+1,&fds,
nullptr,
nullptr,&tv);
1919 s_buffer[s_tail+n]=0;
1921 end=strchr(s_buffer.data(),
'\n');
1925 s_head=strlen(s_buffer.data())+1;
1927 return(s_buffer.data());
1932 char *endptr =
nullptr;
1933 unsigned long n = 0;
1934 unsigned long data_n=0;
1939 if(buf_len!=
nullptr)
1943 int todo=strlen(command);
1944 const char *data=command;
1949 int done=
write(sockfd,(
const void *) data,todo);
1952 lirc_printf(lstate,
"%s: could not send packet\n",
1964 bool good_packet =
false;
1965 bool bad_packet =
false;
1967 while(!good_packet && !bad_packet)
1970 if(
string==
nullptr)
return(-1);
1976 if(strcasecmp(
string,
"BEGIN")!=0)
1983 if(strncasecmp(
string,command,strlen(
string))!=0 ||
1984 strlen(
string)+1!=strlen(command))
1992 if(strcasecmp(
string,
"SUCCESS")==0)
1996 else if(strcasecmp(
string,
"END")==0)
2002 else if(strcasecmp(
string,
"ERROR")==0)
2016 if(strcasecmp(
string,
"END")==0)
2021 else if(strcasecmp(
string,
"DATA")==0)
2030 data_n=strtoul(
string,&endptr,0);
2031 if(!*
string || *endptr)
2047 if(buf!=
nullptr && written+len+1<max)
2049 memcpy(buf+written,
string, len+1);
2053 if(n==data_n) state=
P_END;
2056 if(strcasecmp(
string,
"END")==0)
2072 if(ret_status!=
nullptr)
2076 if(buf_len!=
nullptr)
2080 return (
int) data_n;
2085 char* command =
static_cast<char*
>(malloc((10+strlen(state->
lirc_prog)+1+1) *
sizeof(
char)));
2086 if (command ==
nullptr)
2090 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)
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 QString cleanup(const QString &str)
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 int lirc_readconfig_only_internal(const struct lirc_state *state, const char *file, struct lirc_config **config, int(check)(char *s), std::string &full_name, std::string &sha_bang)
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)