Support for restricting limiting IPC to a set of endpoints. Not enabled by
default, pass -i to service. Do not reply to bogus request types. Reply using sendnb.
This commit is contained in:
parent
19db2b646e
commit
ca8291c815
4 changed files with 184 additions and 122 deletions
|
@ -82,12 +82,20 @@ PUBLIC int main(void)
|
||||||
* Handle the request and send a reply to the caller.
|
* Handle the request and send a reply to the caller.
|
||||||
*/
|
*/
|
||||||
else {
|
else {
|
||||||
|
if (call_nr < RS_RQ_BASE || call_nr >= RS_RQ_BASE+0x100)
|
||||||
|
{
|
||||||
|
/* Ignore invalid requests. Do not try to reply. */
|
||||||
|
printf("RS: got invalid request %d from endpoint %d\n",
|
||||||
|
call_nr, m.m_source);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only root can make calls to rs */
|
/* Only root can make calls to rs */
|
||||||
euid= getpeuid(m.m_source);
|
euid= getpeuid(m.m_source);
|
||||||
if (euid != 0)
|
if (euid != 0)
|
||||||
{
|
{
|
||||||
printf("RS: got unauthorized request from endpoint %d\n",
|
printf("RS: got unauthorized request %d from endpoint %d\n",
|
||||||
m.m_source);
|
call_nr, m.m_source);
|
||||||
m.m_type = EPERM;
|
m.m_type = EPERM;
|
||||||
reply(who_e, &m);
|
reply(who_e, &m);
|
||||||
continue;
|
continue;
|
||||||
|
@ -203,12 +211,11 @@ PRIVATE void reply(who, m_out)
|
||||||
int who; /* replyee */
|
int who; /* replyee */
|
||||||
message *m_out; /* reply message */
|
message *m_out; /* reply message */
|
||||||
{
|
{
|
||||||
/*message m_out;*/ /* reply message */
|
|
||||||
int s; /* send status */
|
int s; /* send status */
|
||||||
|
|
||||||
/*m_out.m_type = result;*/ /* build reply message */
|
s = sendnb(who, m_out); /* send the message */
|
||||||
if (OK != (s=send(who, m_out))) /* send the message */
|
if (s != OK)
|
||||||
panic("RS", "unable to send reply", s);
|
printf("RS: unable to send reply to %d: %d\n", who, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "inc.h"
|
#include "inc.h"
|
||||||
|
#include <ctype.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -260,6 +261,21 @@ message *m_ptr; /* request message pointer */
|
||||||
rp->r_uid= rs_start.rss_uid;
|
rp->r_uid= rs_start.rss_uid;
|
||||||
rp->r_nice= rs_start.rss_nice;
|
rp->r_nice= rs_start.rss_nice;
|
||||||
|
|
||||||
|
if (rs_start.rss_flags & RF_IPC_VALID)
|
||||||
|
{
|
||||||
|
if (rs_start.rss_ipclen+1 > sizeof(rp->r_ipc_list))
|
||||||
|
{
|
||||||
|
printf("rs: ipc list too long for '%s'\n", rp->r_label);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
s=sys_datacopy(m_ptr->m_source, (vir_bytes) rs_start.rss_ipc,
|
||||||
|
SELF, (vir_bytes) rp->r_ipc_list, rs_start.rss_ipclen);
|
||||||
|
if (s != OK) return(s);
|
||||||
|
rp->r_ipc_list[rs_start.rss_ipclen]= '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rp->r_ipc_list[0]= '\0';
|
||||||
|
|
||||||
rp->r_exec= NULL;
|
rp->r_exec= NULL;
|
||||||
if (rs_start.rss_flags & RF_COPY)
|
if (rs_start.rss_flags & RF_COPY)
|
||||||
{
|
{
|
||||||
|
@ -806,11 +822,13 @@ endpoint_t *endpoint;
|
||||||
if (rp->r_dev_nr > 0) { /* set driver map */
|
if (rp->r_dev_nr > 0) { /* set driver map */
|
||||||
if ((s=mapdriver5(rp->r_label, strlen(rp->r_label),
|
if ((s=mapdriver5(rp->r_label, strlen(rp->r_label),
|
||||||
rp->r_dev_nr, rp->r_dev_style, !!use_copy /* force */)) < 0) {
|
rp->r_dev_nr, rp->r_dev_style, !!use_copy /* force */)) < 0) {
|
||||||
report("RS", "couldn't map driver", errno);
|
report("RS", "couldn't map driver (continuing)", errno);
|
||||||
|
#if 0
|
||||||
rp->r_flags |= RS_EXITING; /* expect exit */
|
rp->r_flags |= RS_EXITING; /* expect exit */
|
||||||
if(child_pid > 0) kill(child_pid, SIGKILL); /* kill driver */
|
if(child_pid > 0) kill(child_pid, SIGKILL); /* kill driver */
|
||||||
else report("RS", "didn't kill pid", child_pid);
|
else report("RS", "didn't kill pid", child_pid);
|
||||||
return(s); /* return error */
|
return(s); /* return error */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -970,7 +988,7 @@ struct rproc *rp;
|
||||||
sprintf(incarnation_str, "%d", rp->r_restarts);
|
sprintf(incarnation_str, "%d", rp->r_restarts);
|
||||||
|
|
||||||
if(rs_verbose) {
|
if(rs_verbose) {
|
||||||
printf("RS: should call script '%s'\n", rp->r_script);
|
printf("RS: calling script '%s'\n", rp->r_script);
|
||||||
printf("RS: sevice name: '%s'\n", rp->r_label);
|
printf("RS: sevice name: '%s'\n", rp->r_label);
|
||||||
printf("RS: reason: '%s'\n", reason);
|
printf("RS: reason: '%s'\n", reason);
|
||||||
printf("RS: incarnation: '%s'\n", incarnation_str);
|
printf("RS: incarnation: '%s'\n", incarnation_str);
|
||||||
|
@ -1016,8 +1034,12 @@ struct priv *privp;
|
||||||
{
|
{
|
||||||
int i, src_bits_per_word, dst_bits_per_word, src_word, dst_word,
|
int i, src_bits_per_word, dst_bits_per_word, src_word, dst_word,
|
||||||
src_bit, call_nr, chunk, bit, priv_id, slot_nr;
|
src_bit, call_nr, chunk, bit, priv_id, slot_nr;
|
||||||
|
endpoint_t proc_nr_e;
|
||||||
|
size_t len;
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
|
char *p, *q;
|
||||||
struct rproc *tmp_rp;
|
struct rproc *tmp_rp;
|
||||||
|
char label[MAX_LABEL_LEN+1];
|
||||||
|
|
||||||
/* Clear s_k_call_mask */
|
/* Clear s_k_call_mask */
|
||||||
memset(privp->s_k_call_mask, '\0', sizeof(privp->s_k_call_mask));
|
memset(privp->s_k_call_mask, '\0', sizeof(privp->s_k_call_mask));
|
||||||
|
@ -1050,124 +1072,81 @@ struct priv *privp;
|
||||||
memset(&privp->s_ipc_to, '\0', sizeof(privp->s_ipc_to));
|
memset(&privp->s_ipc_to, '\0', sizeof(privp->s_ipc_to));
|
||||||
memset(&privp->s_ipc_sendrec, '\0', sizeof(privp->s_ipc_sendrec));
|
memset(&privp->s_ipc_sendrec, '\0', sizeof(privp->s_ipc_sendrec));
|
||||||
|
|
||||||
if (strcmp(rp->r_label, "dp8390") == 0)
|
if (strlen(rp->r_ipc_list) != 0)
|
||||||
{
|
{
|
||||||
printf("init_privs: special code for dp8390\n");
|
for (p= rp->r_ipc_list; p[0] != '\0'; p= q)
|
||||||
|
{
|
||||||
|
/* Skip leading space */
|
||||||
|
while (p[0] != '\0' && isspace((unsigned char)p[0]))
|
||||||
|
p++;
|
||||||
|
|
||||||
/* Try to find inet */
|
/* Find start of next word */
|
||||||
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++)
|
q= p;
|
||||||
|
while (q[0] != '\0' && !isspace((unsigned char)q[0]))
|
||||||
|
q++;
|
||||||
|
if (q == p)
|
||||||
|
continue;
|
||||||
|
len= q-p;
|
||||||
|
if (len+1 > sizeof(label))
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"rs:init_privs: bad ipc list entry '.*s' for %s: too long\n",
|
||||||
|
len, p, rp->r_label);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
memcpy(label, p, len);
|
||||||
|
label[len]= '\0';
|
||||||
|
|
||||||
|
if (strcmp(label, "SYSTEM") == 0)
|
||||||
|
proc_nr_e= SYSTEM;
|
||||||
|
else if (strcmp(label, "PM") == 0)
|
||||||
|
proc_nr_e= PM_PROC_NR;
|
||||||
|
else if (strcmp(label, "VFS") == 0)
|
||||||
|
proc_nr_e= FS_PROC_NR;
|
||||||
|
else if (strcmp(label, "RS") == 0)
|
||||||
|
proc_nr_e= RS_PROC_NR;
|
||||||
|
else if (strcmp(label, "LOG") == 0)
|
||||||
|
proc_nr_e= LOG_PROC_NR;
|
||||||
|
else if (strcmp(label, "TTY") == 0)
|
||||||
|
proc_nr_e= TTY_PROC_NR;
|
||||||
|
else if (strcmp(label, "DS") == 0)
|
||||||
|
proc_nr_e= DS_PROC_NR;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Try to find process */
|
||||||
|
for (slot_nr = 0; slot_nr < NR_SYS_PROCS;
|
||||||
|
slot_nr++)
|
||||||
{
|
{
|
||||||
tmp_rp = &rproc[slot_nr];
|
tmp_rp = &rproc[slot_nr];
|
||||||
if (!(tmp_rp->r_flags & RS_IN_USE))
|
if (!(tmp_rp->r_flags & RS_IN_USE))
|
||||||
continue;
|
continue;
|
||||||
if (strcmp(tmp_rp->r_label, "inet") == 0)
|
if (strcmp(tmp_rp->r_label, label) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (slot_nr >= NR_SYS_PROCS)
|
if (slot_nr >= NR_SYS_PROCS)
|
||||||
{
|
|
||||||
printf("init_privs: unable to find inet\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv_id= sys_getprivid(tmp_rp->r_proc_nr_e);
|
|
||||||
if (priv_id < 0)
|
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"init_privs: unable to get priv_id for inet: %d\n",
|
"init_privs: unable to find '%s'\n",
|
||||||
priv_id);
|
label);
|
||||||
return;
|
|
||||||
}
|
|
||||||
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
|
||||||
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
|
||||||
privp->s_ipc_to.chunk[chunk] |= (1 << bit);
|
|
||||||
|
|
||||||
priv_id= sys_getprivid(RS_PROC_NR);
|
|
||||||
if (priv_id < 0)
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"init_privs: unable to get priv_id for RS: %d\n",
|
|
||||||
priv_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
|
||||||
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
|
||||||
privp->s_ipc_to.chunk[chunk] |= (1 << bit);
|
|
||||||
|
|
||||||
priv_id= sys_getprivid(SYSTEM);
|
|
||||||
if (priv_id < 0)
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"init_privs: unable to get priv_id for SYSTEM: %d\n",
|
|
||||||
priv_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
|
||||||
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
|
||||||
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
|
||||||
|
|
||||||
priv_id= sys_getprivid(PM_PROC_NR);
|
|
||||||
if (priv_id < 0)
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"init_privs: unable to get priv_id for PM: %d\n",
|
|
||||||
priv_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
|
||||||
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
|
||||||
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
|
||||||
|
|
||||||
priv_id= sys_getprivid(LOG_PROC_NR);
|
|
||||||
if (priv_id < 0)
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"init_privs: unable to get priv_id for LOG: %d\n",
|
|
||||||
priv_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
|
||||||
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
|
||||||
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
|
||||||
|
|
||||||
priv_id= sys_getprivid(TTY_PROC_NR);
|
|
||||||
if (priv_id < 0)
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"init_privs: unable to get priv_id for TTY: %d\n",
|
|
||||||
priv_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
|
||||||
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
|
||||||
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
|
||||||
|
|
||||||
/* Try to find PCI */
|
|
||||||
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++)
|
|
||||||
{
|
|
||||||
tmp_rp = &rproc[slot_nr];
|
|
||||||
if (!(tmp_rp->r_flags & RS_IN_USE))
|
|
||||||
continue;
|
continue;
|
||||||
if (strcmp(tmp_rp->r_label, "pci") == 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (slot_nr >= NR_SYS_PROCS)
|
proc_nr_e= tmp_rp->r_proc_nr_e;
|
||||||
{
|
|
||||||
printf("init_privs: unable to find PCI\n");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
priv_id= sys_getprivid(tmp_rp->r_proc_nr_e);
|
priv_id= sys_getprivid(proc_nr_e);
|
||||||
if (priv_id < 0)
|
if (priv_id < 0)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"init_privs: unable to get priv_id for PCI: %d\n",
|
"init_privs: unable to get priv_id for '%s': %d\n",
|
||||||
priv_id);
|
label, priv_id);
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
||||||
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
||||||
|
privp->s_ipc_to.chunk[chunk] |= (1 << bit);
|
||||||
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i= 0; i<sizeof(privp->s_ipc_to)*8; i++)
|
for (i= 0; i<sizeof(privp->s_ipc_to)*8; i++)
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
#define MAX_NR_PCI_ID 4 /* maximum number of PCI device IDs */
|
#define MAX_NR_PCI_ID 4 /* maximum number of PCI device IDs */
|
||||||
#define MAX_NR_PCI_CLASS 4 /* maximum number of PCI class IDs */
|
#define MAX_NR_PCI_CLASS 4 /* maximum number of PCI class IDs */
|
||||||
#define MAX_NR_SYSTEM 2 /* should match RSS_NR_SYSTEM */
|
#define MAX_NR_SYSTEM 2 /* should match RSS_NR_SYSTEM */
|
||||||
|
#define MAX_IPC_LIST 256 /* Max size of list for IPC target
|
||||||
|
* process names
|
||||||
|
*/
|
||||||
|
|
||||||
/* Definition of the system process table. This table only has entries for
|
/* Definition of the system process table. This table only has entries for
|
||||||
* the servers and drivers, and thus is not directly indexed by slot number.
|
* the servers and drivers, and thus is not directly indexed by slot number.
|
||||||
|
@ -57,6 +60,7 @@ extern struct rproc {
|
||||||
struct { u32_t class; u32_t mask; } r_pci_class[MAX_NR_PCI_CLASS];
|
struct { u32_t class; u32_t mask; } r_pci_class[MAX_NR_PCI_CLASS];
|
||||||
|
|
||||||
u32_t r_call_mask[MAX_NR_SYSTEM];
|
u32_t r_call_mask[MAX_NR_SYSTEM];
|
||||||
|
char r_ipc_list[MAX_IPC_LIST];
|
||||||
} rproc[NR_SYS_PROCS];
|
} rproc[NR_SYS_PROCS];
|
||||||
|
|
||||||
/* Mapping for fast access to the system process table. */
|
/* Mapping for fast access to the system process table. */
|
||||||
|
|
|
@ -87,6 +87,7 @@ PRIVATE int req_major;
|
||||||
PRIVATE long req_period;
|
PRIVATE long req_period;
|
||||||
PRIVATE char *req_script;
|
PRIVATE char *req_script;
|
||||||
PRIVATE char *req_label;
|
PRIVATE char *req_label;
|
||||||
|
PRIVATE char *req_ipc;
|
||||||
PRIVATE char *req_config = PATH_CONFIG;
|
PRIVATE char *req_config = PATH_CONFIG;
|
||||||
PRIVATE int req_printep;
|
PRIVATE int req_printep;
|
||||||
PRIVATE int class_recurs; /* Nesting level of class statements */
|
PRIVATE int class_recurs; /* Nesting level of class statements */
|
||||||
|
@ -133,9 +134,10 @@ PRIVATE int parse_arguments(int argc, char **argv)
|
||||||
int req_nr;
|
int req_nr;
|
||||||
int c, i;
|
int c, i;
|
||||||
int c_flag;
|
int c_flag;
|
||||||
|
int i_flag=0;
|
||||||
|
|
||||||
c_flag= 0;
|
c_flag= 0;
|
||||||
while (c= getopt(argc, argv, "c?"), c != -1)
|
while (c= getopt(argc, argv, "ci?"), c != -1)
|
||||||
{
|
{
|
||||||
switch(c)
|
switch(c)
|
||||||
{
|
{
|
||||||
|
@ -145,6 +147,9 @@ PRIVATE int parse_arguments(int argc, char **argv)
|
||||||
case 'c':
|
case 'c':
|
||||||
c_flag= 1;
|
c_flag= 1;
|
||||||
break;
|
break;
|
||||||
|
case 'i':
|
||||||
|
i_flag= 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: getopt failed: %c\n",
|
fprintf(stderr, "%s: getopt failed: %c\n",
|
||||||
argv[ARG_NAME], c);
|
argv[ARG_NAME], c);
|
||||||
|
@ -184,6 +189,8 @@ PRIVATE int parse_arguments(int argc, char **argv)
|
||||||
rs_start.rss_flags= 0;
|
rs_start.rss_flags= 0;
|
||||||
if (c_flag)
|
if (c_flag)
|
||||||
rs_start.rss_flags |= RF_COPY;
|
rs_start.rss_flags |= RF_COPY;
|
||||||
|
if (i_flag)
|
||||||
|
rs_start.rss_flags |= RF_IPC_VALID;
|
||||||
|
|
||||||
if (do_run)
|
if (do_run)
|
||||||
{
|
{
|
||||||
|
@ -308,6 +315,7 @@ PRIVATE void fatal(char *fmt, ...)
|
||||||
#define KW_DEVICE "device"
|
#define KW_DEVICE "device"
|
||||||
#define KW_CLASS "class"
|
#define KW_CLASS "class"
|
||||||
#define KW_SYSTEM "system"
|
#define KW_SYSTEM "system"
|
||||||
|
#define KW_IPC "ipc"
|
||||||
|
|
||||||
FORWARD void do_driver(config_t *cpe, config_t *config);
|
FORWARD void do_driver(config_t *cpe, config_t *config);
|
||||||
|
|
||||||
|
@ -673,9 +681,57 @@ struct
|
||||||
{ "SETGRANT", SYS_SETGRANT },
|
{ "SETGRANT", SYS_SETGRANT },
|
||||||
{ "READBIOS", SYS_READBIOS },
|
{ "READBIOS", SYS_READBIOS },
|
||||||
{ "VM_MAP", SYS_VM_MAP },
|
{ "VM_MAP", SYS_VM_MAP },
|
||||||
|
{ "MAPDMAx", SYS_MAPDMAx },
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PRIVATE void do_ipc(config_t *cpe)
|
||||||
|
{
|
||||||
|
char *list;
|
||||||
|
size_t listsize, wordlen;
|
||||||
|
|
||||||
|
list= NULL;
|
||||||
|
listsize= 1;
|
||||||
|
list= malloc(listsize);
|
||||||
|
if (list == NULL)
|
||||||
|
fatal("do_ipc: unable to malloc %d bytes", listsize);
|
||||||
|
list[0]= '\0';
|
||||||
|
|
||||||
|
/* Process a list of process names that are allowed to be
|
||||||
|
* contacted
|
||||||
|
*/
|
||||||
|
for (; cpe; cpe= cpe->next)
|
||||||
|
{
|
||||||
|
if (cpe->flags & CFG_SUBLIST)
|
||||||
|
{
|
||||||
|
fatal("do_ipc: unexpected sublist at %s:%d",
|
||||||
|
cpe->file, cpe->line);
|
||||||
|
}
|
||||||
|
if (cpe->flags & CFG_STRING)
|
||||||
|
{
|
||||||
|
fatal("do_ipc: unexpected string at %s:%d",
|
||||||
|
cpe->file, cpe->line);
|
||||||
|
}
|
||||||
|
|
||||||
|
wordlen= strlen(cpe->word);
|
||||||
|
|
||||||
|
listsize += 1 + wordlen;
|
||||||
|
list= realloc(list, listsize);
|
||||||
|
if (list == NULL)
|
||||||
|
{
|
||||||
|
fatal("do_ipc: unable to realloc %d bytes",
|
||||||
|
listsize);
|
||||||
|
}
|
||||||
|
strcat(list, " ");
|
||||||
|
strcat(list, cpe->word);
|
||||||
|
}
|
||||||
|
printf("do_ipc: got list '%s'\n", list);
|
||||||
|
|
||||||
|
if (req_ipc)
|
||||||
|
fatal("do_ipc: req_ipc is set");
|
||||||
|
req_ipc= list;
|
||||||
|
}
|
||||||
|
|
||||||
PRIVATE void do_system(config_t *cpe)
|
PRIVATE void do_system(config_t *cpe)
|
||||||
{
|
{
|
||||||
int i, call_nr, word, bits_per_word;
|
int i, call_nr, word, bits_per_word;
|
||||||
|
@ -802,6 +858,11 @@ PRIVATE void do_driver(config_t *cpe, config_t *config)
|
||||||
do_system(cpe->next);
|
do_system(cpe->next);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (strcmp(cpe->word, KW_IPC) == 0)
|
||||||
|
{
|
||||||
|
do_ipc(cpe->next);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -941,6 +1002,17 @@ PUBLIC int main(int argc, char **argv)
|
||||||
do_config(progname, req_config);
|
do_config(progname, req_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req_ipc)
|
||||||
|
{
|
||||||
|
rs_start.rss_ipc= req_ipc+1; /* Skip initial space */
|
||||||
|
rs_start.rss_ipclen= strlen(rs_start.rss_ipc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rs_start.rss_ipc= NULL;
|
||||||
|
rs_start.rss_ipclen= 0;
|
||||||
|
}
|
||||||
|
|
||||||
m.RS_CMD_ADDR = (char *) &rs_start;
|
m.RS_CMD_ADDR = (char *) &rs_start;
|
||||||
|
|
||||||
/* Build request message and send the request. */
|
/* Build request message and send the request. */
|
||||||
|
|
Loading…
Reference in a new issue