6 Created: June 1995 by Philip Homburg <philip@f-mnx.phicoh.com>
10 #include "generic/assert.h"
12 #include <sys/svrctl.h>
13 #include "queryparam.h"
15 #include "generic/buf.h"
16 #include "generic/clock.h"
17 #include "generic/event.h"
18 #include "generic/type.h"
19 #include "generic/sr.h"
21 #include "generic/tcp_int.h"
22 #include "generic/udp_int.h"
29 #define MAX_REQ 1024 /* Maximum size of a request */
37 get_userdata_t qf_get_userdata
;
38 put_userdata_t qf_put_userdata
;
45 PRIVATE qp_fd_t qp_fd_table
[QP_FD_NR
];
47 PRIVATE
struct export_param_list inet_ex_list
[]=
49 QP_VARIABLE(sr_fd_table
),
51 QP_VARIABLE(tcp_fd_table
),
52 QP_VARIABLE(tcp_conn_table
),
53 QP_VARIABLE(tcp_cancel_f
),
54 QP_VECTOR(udp_port_table
, udp_port_table
, ip_conf_nr
),
55 QP_VARIABLE(udp_fd_table
),
59 PRIVATE
struct export_params inet_ex_params
= { inet_ex_list
, NULL
};
61 PRIVATE
struct queryvars
{
76 FORWARD
int qp_open
ARGS(( int port
, int srfd
,
77 get_userdata_t get_userdata
, put_userdata_t put_userdata
,
78 put_pkt_t put_pkt
, select_res_t select_res
));
79 FORWARD
void qp_close
ARGS(( int fd
));
80 FORWARD
int qp_read
ARGS(( int fd
, size_t count
));
81 FORWARD
int qp_write
ARGS(( int fd
, size_t count
));
82 FORWARD
int qp_ioctl
ARGS(( int fd
, ioreq_t req
));
83 FORWARD
int qp_cancel
ARGS(( int fd
, int which_operation
));
84 FORWARD
int qp_select
ARGS(( int fd
, unsigned operations
));
85 FORWARD qp_fd_t
*get_qp_fd
ARGS(( int fd
));
86 FORWARD
int do_query
ARGS(( qp_fd_t
*qp_fd
, acc_t
*pkt
, int count
));
87 FORWARD
int qp_getc
ARGS(( void ));
88 FORWARD
void qp_putc
ARGS(( struct queryvars
*qv
, int c
));
89 FORWARD
void qp_buffree
ARGS(( int priority
));
90 #ifdef BUF_CONSISTENCY_CHECK
91 FORWARD
void qp_bufcheck
ARGS(( void ));
98 qp_export(&inet_ex_params
);
100 for (i
= 0; i
<QP_FD_NR
; i
++)
101 qp_fd_table
[i
].qf_flags
= QFF_EMPTY
;
103 #ifndef BUF_CONSISTENCY_CHECK
104 bf_logon(qp_buffree
);
106 bf_logon(qp_buffree
, qp_bufcheck
);
109 sr_add_minor(IPSTAT_MINOR
, 0, qp_open
, qp_close
, qp_read
, qp_write
,
110 qp_ioctl
, qp_cancel
, qp_select
);
113 PRIVATE
int qp_open(port
, srfd
, get_userdata
, put_userdata
, put_pkt
,
117 get_userdata_t get_userdata
;
118 put_userdata_t put_userdata
;
120 select_res_t select_res
;
125 for (i
= 0; i
< QP_FD_NR
; i
++)
127 if (!(qp_fd_table
[i
].qf_flags
& QFF_INUSE
))
132 qp_fd
= &qp_fd_table
[i
];
133 qp_fd
->qf_flags
= QFF_INUSE
;
134 qp_fd
->qf_srfd
= srfd
;
135 qp_fd
->qf_get_userdata
= get_userdata
;
136 qp_fd
->qf_put_userdata
= put_userdata
;
137 qp_fd
->qf_req_pkt
= NULL
;
142 PRIVATE
void qp_close(fd
)
147 qp_fd
= get_qp_fd(fd
);
148 qp_fd
->qf_flags
= QFF_EMPTY
;
149 if (qp_fd
->qf_req_pkt
)
151 bf_afree(qp_fd
->qf_req_pkt
);
152 qp_fd
->qf_req_pkt
= NULL
;
156 PRIVATE
int qp_read(fd
, count
)
164 qp_fd
= get_qp_fd(fd
);
165 pkt
= qp_fd
->qf_req_pkt
;
166 qp_fd
->qf_req_pkt
= NULL
;
170 qp_fd
->qf_put_userdata(qp_fd
->qf_srfd
, EIO
, 0,
171 FALSE
/* !for_ioctl*/);
174 r
= do_query(qp_fd
, pkt
, count
);
175 qp_fd
->qf_put_userdata(qp_fd
->qf_srfd
, r
, 0,
176 FALSE
/* !for_ioctl*/);
180 PRIVATE
int qp_write(fd
, count
)
187 qp_fd
= get_qp_fd(fd
);
190 qp_fd
->qf_get_userdata(qp_fd
->qf_srfd
, ENOMEM
, 0,
191 FALSE
/* !for_ioctl*/);
194 pkt
= qp_fd
->qf_get_userdata(qp_fd
->qf_srfd
, 0, count
,
195 FALSE
/* !for_ioctl*/);
198 qp_fd
->qf_get_userdata(qp_fd
->qf_srfd
, EFAULT
, 0,
199 FALSE
/* !for_ioctl*/);
202 if (qp_fd
->qf_req_pkt
)
204 bf_afree(qp_fd
->qf_req_pkt
);
205 qp_fd
->qf_req_pkt
= NULL
;
207 qp_fd
->qf_req_pkt
= pkt
;
208 qp_fd
->qf_get_userdata(qp_fd
->qf_srfd
, count
, 0,
209 FALSE
/* !for_ioctl*/);
213 PRIVATE
int qp_ioctl(fd
, req
)
219 qp_fd
= get_qp_fd(fd
);
220 qp_fd
->qf_get_userdata(qp_fd
->qf_srfd
, ENOTTY
, 0,
221 TRUE
/* for_ioctl*/);
225 PRIVATE
int qp_cancel(fd
, which_operation
)
229 ip_panic(( "qp_cancel: should not be here, no blocking calls" ));
232 PRIVATE
int qp_select(fd
, operations
)
239 if (operations
& SR_SELECT_READ
)
240 resops
|= SR_SELECT_READ
;
241 if (operations
& SR_SELECT_WRITE
)
242 resops
|= SR_SELECT_WRITE
;
246 PRIVATE qp_fd_t
*get_qp_fd(fd
)
251 assert(fd
>= 0 && fd
< QP_FD_NR
);
252 qp_fd
= &qp_fd_table
[fd
];
253 assert(qp_fd
->qf_flags
& QFF_INUSE
);
257 PRIVATE
int do_query(qp_fd
, pkt
, count
)
267 static char hex
[]= "0123456789ABCDEF";
270 qv
.param
= pkt
; pkt
= NULL
;
274 qv
.rd_bytes_left
= count
;
278 more
= queryparam(qp_getc
, &addr
, &size
);
279 for (n
= 0; n
< size
; n
++) {
280 byte
= ((u8_t
*) addr
)[n
];
281 qp_putc(&qv
, hex
[byte
>> 4]);
282 qp_putc(&qv
, hex
[byte
& 0x0F]);
284 qp_putc(&qv
, more
? ',' : 0);
299 PRIVATE
int qp_getc()
301 /* Return one character of the names to search for. */
303 struct queryvars
*qv
= qvars
;
311 assert(bf_bufsize(pkt
) > 0);
312 c
= ptr2acc_data(pkt
)[0];
313 if (bf_bufsize(pkt
) > 1)
314 qv
->param
= bf_delhead(pkt
, 1);
324 PRIVATE
void qp_putc(qv
, c
)
325 struct queryvars
*qv
;
328 /* Send one character back to the user. */
334 bytes_left
= qv
->rd_bytes_left
;
335 if (qv
->r
|| bytes_left
== 0)
339 assert(off
< sizeof(qv
->outbuf
));
343 qv
->rd_bytes_left
= bytes_left
;
344 if (c
!= '\0' && off
< sizeof(qv
->outbuf
) && bytes_left
!= 0)
351 assert(pkt
->acc_next
== NULL
);
352 memcpy(ptr2acc_data(pkt
), qv
->outbuf
, off
);
354 qv
->r
= qp_fd
->qf_put_userdata(qp_fd
->qf_srfd
, qv
->fd_offset
,
355 pkt
, FALSE
/* !for_ioctl*/ );
356 qv
->fd_offset
+= off
;
360 PRIVATE
void qp_buffree (priority
)
363 /* For the moment, we are not going to free anything */
366 #ifdef BUF_CONSISTENCY_CHECK
367 PRIVATE
void qp_bufcheck()
372 for (i
= 0, qp_fd
= qp_fd_table
; i
<QP_FD_NR
; i
++, qp_fd
++)
374 if (!(qp_fd
->qf_flags
& QFF_INUSE
))
376 if (qp_fd
->qf_req_pkt
)
377 bf_check_acc(qp_fd
->qf_req_pkt
);
383 * $PchId: qp.c,v 1.7 2005/06/28 14:25:25 philip Exp $