2 * Copyright (c) 2001-2002 artofcode LLC.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 #include "ijs_client.h"
33 struct _IjsClientCtx {
36 IjsSendChan send_chan;
37 IjsRecvChan recv_chan;
42 ijs_invoke_server (const char *server_cmd)
45 int fds_to[2], fds_from[2];
47 char helo_buf[8] = IJS_HELO_STR;
49 const char exp_resp_buf[8] = IJS_RESP_STR;
54 if (ijs_exec_server(server_cmd, &fds_to[1], &fds_from[0], &child_pid) < 0)
57 ctx = (IjsClientCtx *)malloc (sizeof(IjsClientCtx));
58 ctx->fd_from = fds_from[0];
59 ctx->child_pid = child_pid;
60 ijs_send_init (&ctx->send_chan, fds_to[1]);
61 ijs_recv_init (&ctx->recv_chan, fds_from[0]);
63 nbytes = write (ctx->send_chan.fd, helo_buf, sizeof(helo_buf));
64 if (nbytes != sizeof(helo_buf))
69 nbytes = read (ctx->recv_chan.fd, resp_buf, sizeof(resp_buf));
70 if (nbytes != sizeof(resp_buf) ||
71 memcmp (resp_buf, exp_resp_buf, sizeof(resp_buf)))
75 /* exchange version information with server */
77 ok = ijs_client_begin_cmd (ctx, IJS_CMD_PING) >= 0;
79 ok = ijs_send_int (&ctx->send_chan, IJS_VERSION) >= 0;
81 ok = ijs_client_send_cmd_wait (ctx) >= 0;
83 ok = ijs_recv_int (&ctx->recv_chan, &version) >= 0;
86 if (version > IJS_VERSION)
87 version = IJS_VERSION;
88 ctx->version = version;
93 close (ctx->send_chan.fd);
94 close (ctx->recv_chan.fd);
103 ijs_client_begin_cmd (IjsClientCtx *ctx, IjsCommand cmd)
105 return ijs_send_begin (&ctx->send_chan, cmd);
109 ijs_client_send_int (IjsClientCtx *ctx, int val)
111 return ijs_send_int (&ctx->send_chan, val);
115 ijs_client_send_cmd (IjsClientCtx *ctx)
117 return ijs_send_buf (&ctx->send_chan);
121 * ijs_client_send_cmd_wait: Send command and wait for ack.
122 * @ctx: IJS client context.
124 * Sends the command in the client context's buffer, and waits for ack.
126 * Return value: 0 on successful ack, otherwise negative.
129 ijs_client_send_cmd_wait (IjsClientCtx *ctx)
133 status = ijs_client_send_cmd (ctx);
136 status = ijs_recv_ack (&ctx->recv_chan);
141 /* This is the blocking version; it's not likely to be efficient */
143 ijs_client_send_data_wait (IjsClientCtx *ctx, IjsJobId job_id,
144 const char *buf, int size)
148 ijs_client_begin_cmd (ctx, IJS_CMD_SEND_DATA_BLOCK);
149 ijs_send_int (&ctx->send_chan, job_id);
150 ijs_send_int (&ctx->send_chan, size);
151 status = ijs_client_send_cmd (ctx);
154 status = write (ctx->send_chan.fd, buf, size);
157 status = ijs_recv_ack (&ctx->recv_chan);
162 ijs_client_open (IjsClientCtx *ctx)
164 ijs_client_begin_cmd (ctx, IJS_CMD_OPEN);
165 return ijs_client_send_cmd_wait (ctx);
169 ijs_client_close (IjsClientCtx *ctx)
171 ijs_client_begin_cmd (ctx, IJS_CMD_CLOSE);
172 return ijs_client_send_cmd_wait (ctx);
176 ijs_client_begin_job (IjsClientCtx *ctx, IjsJobId job_id)
178 ijs_client_begin_cmd (ctx, IJS_CMD_BEGIN_JOB);
179 ijs_send_int (&ctx->send_chan, job_id);
180 return ijs_client_send_cmd_wait (ctx);
184 ijs_client_end_job (IjsClientCtx *ctx, IjsJobId job_id)
186 ijs_client_begin_cmd (ctx, IJS_CMD_END_JOB);
187 ijs_send_int (&ctx->send_chan, job_id);
188 return ijs_client_send_cmd_wait (ctx);
192 * Return value: data block size if nonnegative, or error code if
196 ijs_client_list_params (IjsClientCtx *ctx, IjsJobId job_id,
197 char *value, int value_size)
201 ijs_client_begin_cmd (ctx, IJS_CMD_LIST_PARAMS);
202 ijs_send_int (&ctx->send_chan, job_id);
203 status = ijs_client_send_cmd (ctx);
206 status = ijs_recv_ack (&ctx->recv_chan);
209 status = ijs_recv_block (&ctx->recv_chan, value, value_size);
214 * Return value: data block size if nonnegative, or error code if
218 ijs_client_enum_param (IjsClientCtx *ctx, IjsJobId job_id,
220 char *value, int value_size)
222 int key_size = strlen (key);
225 ijs_client_begin_cmd (ctx, IJS_CMD_ENUM_PARAM);
226 ijs_send_int (&ctx->send_chan, job_id);
227 status = ijs_send_block (&ctx->send_chan, key, key_size + 1);
230 status = ijs_client_send_cmd (ctx);
233 status = ijs_recv_ack (&ctx->recv_chan);
236 status = ijs_recv_block (&ctx->recv_chan, value, value_size);
241 ijs_client_set_param (IjsClientCtx *ctx, IjsJobId job_id,
243 const char *value, int value_size)
245 int key_size = strlen (key);
248 ijs_client_begin_cmd (ctx, IJS_CMD_SET_PARAM);
249 ijs_send_int (&ctx->send_chan, job_id);
250 ijs_send_int (&ctx->send_chan, key_size + 1 + value_size);
251 status = ijs_send_block (&ctx->send_chan, key, key_size+1);
254 status = ijs_send_block (&ctx->send_chan, value, value_size);
257 status = ijs_client_send_cmd (ctx);
260 status = ijs_recv_ack (&ctx->recv_chan);
265 * Return value: data block size if nonnegative, or error code if
269 ijs_client_get_param (IjsClientCtx *ctx, IjsJobId job_id,
271 char *value, int value_size)
273 int key_size = strlen (key);
276 ijs_client_begin_cmd (ctx, IJS_CMD_GET_PARAM);
277 ijs_send_int (&ctx->send_chan, job_id);
278 status = ijs_send_block (&ctx->send_chan, key, key_size + 1);
281 status = ijs_client_send_cmd (ctx);
284 status = ijs_recv_ack (&ctx->recv_chan);
287 status = ijs_recv_block (&ctx->recv_chan, value, value_size);
292 ijs_client_begin_page (IjsClientCtx *ctx, IjsJobId job_id)
294 ijs_client_begin_cmd (ctx, IJS_CMD_BEGIN_PAGE);
295 ijs_send_int (&ctx->send_chan, job_id);
296 return ijs_client_send_cmd_wait (ctx);
300 ijs_client_end_page (IjsClientCtx *ctx, IjsJobId job_id)
302 ijs_client_begin_cmd (ctx, IJS_CMD_END_PAGE);
303 ijs_send_int (&ctx->send_chan, job_id);
304 return ijs_client_send_cmd_wait (ctx);
308 ijs_client_get_version (IjsClientCtx *ctx)