1 /*
2 * cmd_solparm.c
3 *
4 * A command interpreter for OpenIPMI
5 *
6 * Author: MontaVista Software, Inc.
7 * Corey Minyard <minyard@mvista.com>
8 * source@mvista.com
9 *
10 * Copyright 2004 MontaVista Software Inc.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this program; if not, write to the Free
31 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 */
33
34 #include <errno.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <OpenIPMI/ipmiif.h>
40 #include <OpenIPMI/ipmi_solparm.h>
41 #include <OpenIPMI/ipmi_cmdlang.h>
42 #include <OpenIPMI/ipmi_mc.h>
43
44 /* Internal includes, do not use in your programs */
45 #include <OpenIPMI/internal/ipmi_malloc.h>
46 #include <OpenIPMI/internal/locked_list.h>
47
48 static locked_list_t *solcs;
49
50 static void
solparm_list_handler(ipmi_solparm_t * solparm,void * cb_data)51 solparm_list_handler(ipmi_solparm_t *solparm, void *cb_data)
52 {
53 ipmi_cmd_info_t *cmd_info = cb_data;
54 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
55 char solparm_name[IPMI_SOLPARM_NAME_LEN];
56
57 if (cmdlang->err)
58 return;
59
60 ipmi_solparm_get_name(solparm, solparm_name, sizeof(solparm_name));
61
62 ipmi_cmdlang_out(cmd_info, "Name", solparm_name);
63 }
64
65 static void
solparm_list(ipmi_domain_t * domain,void * cb_data)66 solparm_list(ipmi_domain_t *domain, void *cb_data)
67 {
68 ipmi_cmd_info_t *cmd_info = cb_data;
69 char domain_name[IPMI_DOMAIN_NAME_LEN];
70
71 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
72 ipmi_cmdlang_out(cmd_info, "Domain", NULL);
73 ipmi_cmdlang_down(cmd_info);
74 ipmi_cmdlang_out(cmd_info, "Name", domain_name);
75 ipmi_cmdlang_out(cmd_info, "SOLPARMs", NULL);
76 ipmi_cmdlang_down(cmd_info);
77 ipmi_solparm_iterate_solparms(domain, solparm_list_handler, cmd_info);
78 ipmi_cmdlang_up(cmd_info);
79 ipmi_cmdlang_up(cmd_info);
80 }
81
82 static void
get_mc_name(ipmi_mc_t * mc,void * cb_data)83 get_mc_name(ipmi_mc_t *mc, void *cb_data)
84 {
85 ipmi_cmd_info_t *cmd_info = cb_data;
86 char mc_name[IPMI_MC_NAME_LEN];
87
88 ipmi_mc_get_name(mc, mc_name, sizeof(mc_name));
89 ipmi_cmdlang_out(cmd_info, "MC", mc_name);
90 }
91
92 static void
solparm_info(ipmi_solparm_t * solparm,void * cb_data)93 solparm_info(ipmi_solparm_t *solparm, void *cb_data)
94 {
95 ipmi_cmd_info_t *cmd_info = cb_data;
96 int rv;
97 char solparm_name[IPMI_SOLPARM_NAME_LEN];
98
99 ipmi_solparm_get_name(solparm, solparm_name, sizeof(solparm_name));
100
101 ipmi_cmdlang_out(cmd_info, "SOLPARM", NULL);
102 ipmi_cmdlang_down(cmd_info);
103 ipmi_cmdlang_out(cmd_info, "Name", solparm_name);
104 rv = ipmi_mc_pointer_cb(ipmi_solparm_get_mc_id(solparm), get_mc_name,
105 cmd_info);
106 if (rv) {
107 ipmi_cmdlang_out_int(cmd_info, "Error getting MC", rv);
108 }
109 ipmi_cmdlang_out_int(cmd_info, "Channel",
110 ipmi_solparm_get_channel(solparm));
111 ipmi_cmdlang_up(cmd_info);
112 }
113
114 static void
solparm_new(ipmi_mc_t * mc,void * cb_data)115 solparm_new(ipmi_mc_t *mc, void *cb_data)
116 {
117 ipmi_cmd_info_t *cmd_info = cb_data;
118 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
119 int channel;
120 int rv;
121 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
122 int argc = ipmi_cmdlang_get_argc(cmd_info);
123 char **argv = ipmi_cmdlang_get_argv(cmd_info);
124 ipmi_solparm_t *solparm;
125 char solparm_name[IPMI_SOLPARM_NAME_LEN];
126
127 if ((argc - curr_arg) < 1) {
128 /* Not enough parameters */
129 cmdlang->errstr = "Not enough parameters";
130 cmdlang->err = EINVAL;
131 goto out_err;
132 }
133
134 ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
135 if (cmdlang->err) {
136 cmdlang->errstr = "channel invalid";
137 goto out_err;
138 }
139 curr_arg++;
140
141 rv = ipmi_solparm_alloc(mc, channel, &solparm);
142 if (rv) {
143 cmdlang->errstr = "Error from ipmi_solparm_alloc";
144 cmdlang->err = rv;
145 goto out_err;
146 }
147
148 ipmi_solparm_get_name(solparm, solparm_name, sizeof(solparm_name));
149 ipmi_cmdlang_out(cmd_info, "SOLPARM", solparm_name);
150
151 return;
152
153 out_err:
154 ipmi_mc_get_name(mc, cmdlang->objstr,
155 cmdlang->objstr_len);
156 cmdlang->location = "cmd_solparm.c(solparm_new)";
157 }
158
159 typedef struct solparm_info_s
160 {
161 char name[IPMI_SOLPARM_NAME_LEN];
162 ipmi_cmd_info_t *cmd_info;
163 } solparm_info_t;
164
165 static void
solparm_close_done(ipmi_solparm_t * solparm,int err,void * cb_data)166 solparm_close_done(ipmi_solparm_t *solparm, int err, void *cb_data)
167 {
168 solparm_info_t *info = cb_data;
169 ipmi_cmd_info_t *cmd_info = info->cmd_info;
170 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
171
172 ipmi_cmdlang_lock(cmd_info);
173 if (err) {
174 ipmi_solparm_get_name(solparm, cmdlang->objstr,
175 cmdlang->objstr_len);
176 cmdlang->errstr = "Error closing SOLPARM";
177 cmdlang->err = err;
178 cmdlang->location = "cmd_solparm.c(solparm_close_done)";
179 goto out;
180 }
181
182 ipmi_cmdlang_out(cmd_info, "SOLPARM destroyed", info->name);
183
184 out:
185 ipmi_cmdlang_unlock(cmd_info);
186 ipmi_cmdlang_cmd_info_put(cmd_info);
187 ipmi_mem_free(info);
188 }
189
190 static void
solparm_close(ipmi_solparm_t * solparm,void * cb_data)191 solparm_close(ipmi_solparm_t *solparm, void *cb_data)
192 {
193 ipmi_cmd_info_t *cmd_info = cb_data;
194 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
195 int rv;
196 solparm_info_t *info;
197
198 info = ipmi_mem_alloc(sizeof(*info));
199 if (!info) {
200 cmdlang->errstr = "Out of memory";
201 cmdlang->err = ENOMEM;
202 goto out_err;
203 }
204 info->cmd_info = cmd_info;
205 ipmi_solparm_get_name(solparm, info->name, sizeof(info->name));
206
207 ipmi_cmdlang_cmd_info_get(cmd_info);
208 rv = ipmi_solparm_destroy(solparm, solparm_close_done, info);
209 if (rv) {
210 ipmi_cmdlang_cmd_info_put(cmd_info);
211 ipmi_solparm_get_name(solparm, cmdlang->objstr,
212 cmdlang->objstr_len);
213 cmdlang->errstr = "Error closing SOLPARM";
214 cmdlang->err = rv;
215 ipmi_mem_free(info);
216 }
217 return;
218
219 out_err:
220 cmdlang->location = "cmd_solparm.c(solparm_close)";
221 }
222
223 #define SOL_CONFIG_NAME_LEN 80
224 typedef struct sol_config_info_s
225 {
226 char name[SOL_CONFIG_NAME_LEN];
227 ipmi_sol_config_t *config;
228 } sol_config_info_t;
229
230 static unsigned int unique_num = 0;
231
232 typedef struct find_config_s
233 {
234 char *name;
235 ipmi_sol_config_t *config;
236 int delete;
237 } find_config_t;
238
239 static int
find_config_handler(void * cb_data,void * item1,void * item2)240 find_config_handler(void *cb_data, void *item1, void *item2)
241 {
242 sol_config_info_t *info = item1;
243 find_config_t *find = cb_data;
244
245 if (strcmp(find->name, info->name) == 0) {
246 find->config = info->config;
247 if (find->delete) {
248 locked_list_remove(solcs, item1, item2);
249 ipmi_mem_free(info);
250 }
251 return LOCKED_LIST_ITER_STOP;
252 }
253
254 return LOCKED_LIST_ITER_CONTINUE;
255 }
256
257 static ipmi_sol_config_t *
find_config(char * name,int delete)258 find_config(char *name, int delete)
259 {
260 find_config_t find;
261
262 find.name = name;
263 find.config = NULL;
264 find.delete = delete;
265 locked_list_iterate(solcs, find_config_handler, &find);
266 return find.config;
267 }
268
269 typedef void (*lp_set)(ipmi_cmd_info_t *cmd_info, char *val,
270 ipmi_sol_config_t *solc, void *func);
271 typedef void (*lp_out)(ipmi_cmd_info_t *cmd_info, char *name,
272 ipmi_sol_config_t *solc, void *func);
273 typedef struct lp_item_s
274 {
275 lp_set set;
276 lp_out out;
277 } lp_item_t;
278
279 static void
set_retint(ipmi_cmd_info_t * cmd_info,char * val,ipmi_sol_config_t * solc,void * func)280 set_retint(ipmi_cmd_info_t *cmd_info, char *val,
281 ipmi_sol_config_t *solc, void *func)
282 {
283 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
284 int (*f)(ipmi_sol_config_t *l, unsigned int v) = func;
285 int v;
286
287 ipmi_cmdlang_get_int(val, &v, cmd_info);
288 if (!cmdlang->err) {
289 cmdlang->err = f(solc, v);
290 if (cmdlang->err) {
291 cmdlang->errstr = "Error setting parameter";
292 }
293 }
294 }
295 static void
out_retint(ipmi_cmd_info_t * cmd_info,char * name,ipmi_sol_config_t * solc,void * func)296 out_retint(ipmi_cmd_info_t *cmd_info, char *name,
297 ipmi_sol_config_t *solc, void *func)
298 {
299 unsigned int (*f)(ipmi_sol_config_t *l) = func;
300 ipmi_cmdlang_out_int(cmd_info, name, f(solc));
301 }
302 static lp_item_t lp_retint = {set_retint, out_retint};
303
304 static void
set_retbool(ipmi_cmd_info_t * cmd_info,char * val,ipmi_sol_config_t * solc,void * func)305 set_retbool(ipmi_cmd_info_t *cmd_info, char *val,
306 ipmi_sol_config_t *solc, void *func)
307 {
308 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
309 int (*f)(ipmi_sol_config_t *l, unsigned int v) = func;
310 int v;
311
312 ipmi_cmdlang_get_bool(val, &v, cmd_info);
313 if (!cmdlang->err) {
314 cmdlang->err = f(solc, v);
315 if (cmdlang->err) {
316 cmdlang->errstr = "Error setting parameter";
317 }
318 }
319 }
320 static void
out_retbool(ipmi_cmd_info_t * cmd_info,char * name,ipmi_sol_config_t * solc,void * func)321 out_retbool(ipmi_cmd_info_t *cmd_info, char *name,
322 ipmi_sol_config_t *solc, void *func)
323 {
324 unsigned int (*f)(ipmi_sol_config_t *l) = func;
325 ipmi_cmdlang_out_bool(cmd_info, name, f(solc));
326 }
327 static lp_item_t lp_retbool = {set_retbool, out_retbool};
328
329 static void
set_int(ipmi_cmd_info_t * cmd_info,char * val,ipmi_sol_config_t * solc,void * func)330 set_int(ipmi_cmd_info_t *cmd_info, char *val,
331 ipmi_sol_config_t *solc, void *func)
332 {
333 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
334 int (*f)(ipmi_sol_config_t *l, unsigned int v) = func;
335 int v;
336
337 ipmi_cmdlang_get_int(val, &v, cmd_info);
338 if (!cmdlang->err) {
339 cmdlang->err = f(solc, v);
340 if (cmdlang->err) {
341 cmdlang->errstr = "Error setting parameter";
342 }
343 }
344 }
345 static void
out_int(ipmi_cmd_info_t * cmd_info,char * name,ipmi_sol_config_t * solc,void * func)346 out_int(ipmi_cmd_info_t *cmd_info, char *name,
347 ipmi_sol_config_t *solc, void *func)
348 {
349 unsigned int v;
350 int rv;
351 int (*f)(ipmi_sol_config_t *l, unsigned int *v) = func;
352
353 rv = f(solc, &v);
354 if (!rv)
355 ipmi_cmdlang_out_int(cmd_info, name, v);
356 }
357 static lp_item_t lp_int = {set_int, out_int};
358
359 static struct lps_s
360 {
361 char *name;
362 lp_item_t *lpi;
363 void *get_func;
364 void *set_func;
365 } lps[] =
366 /* read-only */
367 #define FR(name, type) { #name, &lp_ ## type, ipmi_solconfig_get_ ## name, \
368 NULL }
369 /* Writable */
370 #define F(name, type) { #name, &lp_ ## type, ipmi_solconfig_get_ ## name, \
371 ipmi_solconfig_set_ ## name }
372 {
373 F(enable, retbool),
374 F(force_payload_encryption, retbool),
375 F(force_payload_authentication, retbool),
376 F(privilege_level, retint),
377 F(char_accumulation_interval, retint),
378 F(char_send_threshold, retint),
379 F(retry_count, retint),
380 F(retry_interval, retint),
381 F(port_number, retint),
382 FR(payload_channel, int),
383 { NULL }
384 };
385
386 static void
config_info(ipmi_cmd_info_t * cmd_info,ipmi_sol_config_t * config)387 config_info(ipmi_cmd_info_t *cmd_info, ipmi_sol_config_t *config)
388 {
389 int i;
390
391 /* Basic items */
392 for (i=0; lps[i].name; i++) {
393 lp_item_t *lp = lps[i].lpi;
394 lp->out(cmd_info, lps[i].name, config, lps[i].get_func);
395 }
396 }
397
398 static void
solparm_config_get_done(ipmi_solparm_t * solparm,int err,ipmi_sol_config_t * config,void * cb_data)399 solparm_config_get_done(ipmi_solparm_t *solparm,
400 int err,
401 ipmi_sol_config_t *config,
402 void *cb_data)
403 {
404 ipmi_cmd_info_t *cmd_info = cb_data;
405 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
406 char solparm_name[IPMI_SOLPARM_NAME_LEN];
407 sol_config_info_t *info;
408
409 ipmi_cmdlang_lock(cmd_info);
410 if (err) {
411 cmdlang->errstr = "Error getting SOLPARM";
412 cmdlang->err = err;
413 goto out;
414 }
415
416 ipmi_solparm_get_name(solparm, solparm_name, sizeof(solparm_name));
417
418 info = ipmi_mem_alloc(sizeof(*info));
419 if (!info) {
420 cmdlang->errstr = "Out of memory";
421 cmdlang->err = ENOMEM;
422 ipmi_sol_free_config(config);
423 goto out;
424 }
425 snprintf(info->name, sizeof(info->name), "%s.%u",
426 solparm_name, unique_num);
427 info->config = config;
428 if (!locked_list_add(solcs, info, NULL)) {
429 cmdlang->errstr = "Out of memory";
430 cmdlang->err = ENOMEM;
431 ipmi_sol_free_config(config);
432 ipmi_mem_free(info);
433 goto out;
434 }
435 unique_num++;
436
437 ipmi_cmdlang_out(cmd_info, "SOLPARM Config", NULL);
438 ipmi_cmdlang_down(cmd_info);
439 ipmi_cmdlang_out(cmd_info, "Name", info->name);
440 config_info(cmd_info, config);
441 ipmi_cmdlang_up(cmd_info);
442
443 out:
444 if (cmdlang->err) {
445 ipmi_solparm_get_name(solparm, cmdlang->objstr,
446 cmdlang->objstr_len);
447 cmdlang->location = "cmd_solparm.c(solparm_config_get_done)";
448 }
449 ipmi_cmdlang_unlock(cmd_info);
450 ipmi_cmdlang_cmd_info_put(cmd_info);
451 }
452
453 static void
solparm_config_get(ipmi_solparm_t * solparm,void * cb_data)454 solparm_config_get(ipmi_solparm_t *solparm, void *cb_data)
455 {
456 ipmi_cmd_info_t *cmd_info = cb_data;
457 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
458 int rv;
459
460 ipmi_cmdlang_cmd_info_get(cmd_info);
461 rv = ipmi_sol_get_config(solparm, solparm_config_get_done, cmd_info);
462 if (rv) {
463 ipmi_solparm_get_name(solparm, cmdlang->objstr,
464 cmdlang->objstr_len);
465 ipmi_cmdlang_cmd_info_put(cmd_info);
466 cmdlang->errstr = "Error getting SOLPARM";
467 cmdlang->err = rv;
468 cmdlang->location = "cmd_solparm.c(solparm_config_get)";
469 }
470 }
471
472 typedef struct lp_config_op_s
473 {
474 char name[SOL_CONFIG_NAME_LEN];
475 ipmi_cmd_info_t *cmd_info;
476 } lp_config_op_t;
477
478 static void
solparm_config_set_done(ipmi_solparm_t * solparm,int err,void * cb_data)479 solparm_config_set_done(ipmi_solparm_t *solparm,
480 int err,
481 void *cb_data)
482 {
483 lp_config_op_t *info = cb_data;
484 ipmi_cmd_info_t *cmd_info = info->cmd_info;
485 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
486
487 ipmi_cmdlang_lock(cmd_info);
488 if (err) {
489 ipmi_solparm_get_name(solparm, cmdlang->objstr,
490 cmdlang->objstr_len);
491 cmdlang->errstr = "Error setting SOLPARM";
492 cmdlang->err = err;
493 cmdlang->location = "cmd_solparm.c(solparm_config_set_done)";
494 goto out;
495 }
496
497 ipmi_cmdlang_out(cmd_info, "SOLPARM config set", info->name);
498
499 out:
500 ipmi_mem_free(info);
501 ipmi_cmdlang_unlock(cmd_info);
502 ipmi_cmdlang_cmd_info_put(cmd_info);
503 }
504
505 static void
solparm_config_set(ipmi_solparm_t * solparm,void * cb_data)506 solparm_config_set(ipmi_solparm_t *solparm, void *cb_data)
507 {
508 ipmi_cmd_info_t *cmd_info = cb_data;
509 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
510 int rv;
511 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
512 int argc = ipmi_cmdlang_get_argc(cmd_info);
513 char **argv = ipmi_cmdlang_get_argv(cmd_info);
514 ipmi_sol_config_t *solc;
515 lp_config_op_t *info = cb_data;
516 char *name;
517
518 if ((argc - curr_arg) < 1) {
519 /* Not enough parameters */
520 cmdlang->errstr = "Not enough parameters";
521 cmdlang->err = EINVAL;
522 goto out_err;
523 }
524
525 name = argv[curr_arg];
526 curr_arg++;
527
528 solc = find_config(name, 0);
529 if (!solc) {
530 cmdlang->errstr = "Invalid SOL config";
531 cmdlang->err = EINVAL;
532 goto out_err;
533 }
534
535 info = ipmi_mem_alloc(sizeof(*info));
536 if (!info) {
537 cmdlang->errstr = "Out of memory";
538 cmdlang->err = ENOMEM;
539 goto out_err;
540 }
541 info->cmd_info = cmd_info;
542 strncpy(info->name, name, sizeof(info->name) - 1);
543 info->name[sizeof(info->name) - 1] = '\0';
544
545 ipmi_cmdlang_cmd_info_get(cmd_info);
546 rv = ipmi_sol_set_config(solparm, solc, solparm_config_set_done, info);
547 if (rv) {
548 ipmi_cmdlang_cmd_info_put(cmd_info);
549 cmdlang->errstr = "Error setting SOLPARM";
550 cmdlang->err = rv;
551 ipmi_mem_free(info);
552 goto out_err;
553 }
554
555 return;
556
557 out_err:
558 ipmi_solparm_get_name(solparm, cmdlang->objstr,
559 cmdlang->objstr_len);
560 cmdlang->location = "cmd_solparm.c(solparm_config_set)";
561 }
562
563 static void
solparm_config_unlock_done(ipmi_solparm_t * solparm,int err,void * cb_data)564 solparm_config_unlock_done(ipmi_solparm_t *solparm,
565 int err,
566 void *cb_data)
567 {
568 lp_config_op_t *info = cb_data;
569 ipmi_cmd_info_t *cmd_info = info->cmd_info;
570 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
571
572 ipmi_cmdlang_lock(cmd_info);
573 if (err) {
574 ipmi_solparm_get_name(solparm, cmdlang->objstr,
575 cmdlang->objstr_len);
576 cmdlang->errstr = "Error unlocking SOLPARM";
577 cmdlang->err = err;
578 cmdlang->location = "cmd_solparm.c(solparm_config_unlock_done)";
579 goto out;
580 }
581
582 ipmi_cmdlang_out(cmd_info, "SOLPARM config unlocked", info->name);
583
584 out:
585 ipmi_mem_free(info);
586 ipmi_cmdlang_unlock(cmd_info);
587 ipmi_cmdlang_cmd_info_put(cmd_info);
588 }
589
590 static void
solparm_config_unlock(ipmi_solparm_t * solparm,void * cb_data)591 solparm_config_unlock(ipmi_solparm_t *solparm, void *cb_data)
592 {
593 ipmi_cmd_info_t *cmd_info = cb_data;
594 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
595 int rv;
596 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
597 int argc = ipmi_cmdlang_get_argc(cmd_info);
598 char **argv = ipmi_cmdlang_get_argv(cmd_info);
599 ipmi_sol_config_t *solc;
600 lp_config_op_t *info = cb_data;
601 char *name;
602
603 if ((argc - curr_arg) < 1) {
604 /* Not enough parameters */
605 cmdlang->errstr = "Not enough parameters";
606 cmdlang->err = EINVAL;
607 goto out_err;
608 }
609
610 name = argv[curr_arg];
611 curr_arg++;
612 solc = find_config(name, 0);
613 if (!solc) {
614 cmdlang->errstr = "Invalid SOL config";
615 cmdlang->err = EINVAL;
616 goto out_err;
617 }
618
619 info = ipmi_mem_alloc(sizeof(*info));
620 if (!info) {
621 cmdlang->errstr = "Out of memory";
622 cmdlang->err = ENOMEM;
623 goto out_err;
624 }
625 info->cmd_info = cmd_info;
626 strncpy(info->name, name, sizeof(info->name) - 1);
627 info->name[sizeof(info->name) - 1] = '\0';
628
629 ipmi_cmdlang_cmd_info_get(cmd_info);
630 rv = ipmi_sol_clear_lock(solparm, solc, solparm_config_unlock_done, info);
631 if (rv) {
632 ipmi_cmdlang_cmd_info_put(cmd_info);
633 cmdlang->errstr = "Error getting SOLPARM";
634 cmdlang->err = rv;
635 ipmi_mem_free(info);
636 goto out_err;
637 }
638
639 return;
640
641 out_err:
642 ipmi_solparm_get_name(solparm, cmdlang->objstr,
643 cmdlang->objstr_len);
644 cmdlang->location = "cmd_solparm.c(solparm_config_unlock)";
645 }
646
647 static void
solparm_config_close(ipmi_cmd_info_t * cmd_info)648 solparm_config_close(ipmi_cmd_info_t *cmd_info)
649 {
650 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
651 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
652 int argc = ipmi_cmdlang_get_argc(cmd_info);
653 char **argv = ipmi_cmdlang_get_argv(cmd_info);
654 ipmi_sol_config_t *solc;
655 char *solc_name;
656
657 if ((argc - curr_arg) < 1) {
658 /* Not enough parameters */
659 cmdlang->errstr = "Not enough parameters";
660 cmdlang->err = EINVAL;
661 solc_name = "";
662 goto out_err;
663 }
664 solc_name = argv[curr_arg];
665
666 solc = find_config(solc_name, 1);
667 if (!solc) {
668 cmdlang->errstr = "Invalid SOL config";
669 cmdlang->err = EINVAL;
670 goto out_err;
671 }
672
673 ipmi_sol_free_config(solc);
674 ipmi_cmdlang_out(cmd_info, "SOLPARM config destroyed", solc_name);
675 return;
676
677 out_err:
678 strncpy(cmdlang->objstr, solc_name, cmdlang->objstr_len);
679 cmdlang->location = "cmd_solparm.c(solparm_config_close)";
680 }
681
682 static int
solparm_config_list_handler(void * cb_data,void * item1,void * item2)683 solparm_config_list_handler(void *cb_data, void *item1, void *item2)
684 {
685 ipmi_cmd_info_t *cmd_info = cb_data;
686 sol_config_info_t *info = item1;
687
688 ipmi_cmdlang_out(cmd_info, "Name", info->name);
689 return LOCKED_LIST_ITER_CONTINUE;
690 }
691
692 static void
solparm_config_list(ipmi_cmd_info_t * cmd_info)693 solparm_config_list(ipmi_cmd_info_t *cmd_info)
694 {
695 ipmi_cmdlang_out(cmd_info, "SOLPARM Configs", NULL);
696 ipmi_cmdlang_down(cmd_info);
697 locked_list_iterate(solcs, solparm_config_list_handler, cmd_info);
698 ipmi_cmdlang_up(cmd_info);
699 }
700
701 static int
solparm_config_info_handler(void * cb_data,void * item1,void * item2)702 solparm_config_info_handler(void *cb_data, void *item1, void *item2)
703 {
704 ipmi_cmd_info_t *cmd_info = cb_data;
705 sol_config_info_t *info = item1;
706
707 ipmi_cmdlang_out(cmd_info, "SOLPARM Config", NULL);
708 ipmi_cmdlang_down(cmd_info);
709 ipmi_cmdlang_out(cmd_info, "Name", info->name);
710 config_info(cmd_info, info->config);
711 ipmi_cmdlang_up(cmd_info);
712 return LOCKED_LIST_ITER_CONTINUE;
713 }
714
715 static void
solparm_config_info(ipmi_cmd_info_t * cmd_info)716 solparm_config_info(ipmi_cmd_info_t *cmd_info)
717 {
718 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
719 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
720 int argc = ipmi_cmdlang_get_argc(cmd_info);
721 char **argv = ipmi_cmdlang_get_argv(cmd_info);
722 ipmi_sol_config_t *solc;
723
724 if ((argc - curr_arg) < 1) {
725 locked_list_iterate(solcs, solparm_config_info_handler, cmd_info);
726 } else {
727 solc = find_config(argv[curr_arg], 0);
728 if (!solc) {
729 cmdlang->errstr = "Invalid SOL config";
730 cmdlang->err = EINVAL;
731 goto out_err;
732 }
733 ipmi_cmdlang_out(cmd_info, "SOLPARM Config", NULL);
734 ipmi_cmdlang_down(cmd_info);
735 ipmi_cmdlang_out(cmd_info, "Name", argv[curr_arg]);
736 config_info(cmd_info, solc);
737 ipmi_cmdlang_up(cmd_info);
738 }
739 return;
740
741 out_err:
742 strncpy(cmdlang->objstr, argv[curr_arg], cmdlang->objstr_len);
743 cmdlang->location = "cmd_solparm.c(solparm_config_info)";
744 }
745
746 static void
solparm_config_update(ipmi_cmd_info_t * cmd_info)747 solparm_config_update(ipmi_cmd_info_t *cmd_info)
748 {
749 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
750 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
751 int argc = ipmi_cmdlang_get_argc(cmd_info);
752 char **argv = ipmi_cmdlang_get_argv(cmd_info);
753 ipmi_sol_config_t *solc;
754 int i;
755 char *name;
756 char *val;
757 char *solc_name;
758
759 if ((argc - curr_arg) < 3) {
760 /* Not enough parameters */
761 cmdlang->errstr = "Not enough parameters";
762 cmdlang->err = EINVAL;
763 solc_name = "";
764 goto out_err;
765 }
766 solc_name = argv[curr_arg];
767 curr_arg++;
768
769 solc = find_config(solc_name, 0);
770 if (!solc) {
771 cmdlang->errstr = "Invalid SOL config";
772 cmdlang->err = EINVAL;
773 goto out_err;
774 }
775
776 name = argv[curr_arg];
777 curr_arg++;
778 val = argv[curr_arg];
779 curr_arg++;
780
781 /* Basic items */
782 for (i=0; lps[i].name; i++) {
783 if (strcmp(lps[i].name, name) == 0) {
784 lp_item_t *lp = lps[i].lpi;
785 if (!lp->set) {
786 cmdlang->errstr = "Parameter is read-only";
787 cmdlang->err = EINVAL;
788 goto out_err;
789 }
790 lp->set(cmd_info, val, solc, lps[i].set_func);
791 goto out;
792 }
793 }
794
795 cmdlang->errstr = "Invalid parameter name";
796 cmdlang->err = EINVAL;
797 goto out_err;
798
799 out:
800 ipmi_cmdlang_out(cmd_info, "SOLPARM config updated", solc_name);
801 return;
802
803 out_err:
804 strncpy(cmdlang->objstr, solc_name, cmdlang->objstr_len);
805 cmdlang->location = "cmd_solparm.c(solparm_config_update)";
806 }
807
808 typedef struct solparm_mc_unlock_s
809 {
810 char name[IPMI_MC_NAME_LEN];
811 ipmi_cmd_info_t *cmd_info;
812 } solparm_mc_unlock_t;
813
814 static void
solparm_unlock_mc_done(ipmi_solparm_t * solparm,int err,void * cb_data)815 solparm_unlock_mc_done(ipmi_solparm_t *solparm, int err, void *cb_data)
816 {
817 solparm_mc_unlock_t *info = cb_data;
818 ipmi_cmd_info_t *cmd_info = info->cmd_info;
819 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
820
821 ipmi_cmdlang_lock(cmd_info);
822 if (err) {
823 ipmi_solparm_get_name(solparm, cmdlang->objstr,
824 cmdlang->objstr_len);
825 cmdlang->errstr = "Error unlocking MC SOLPARM";
826 cmdlang->err = err;
827 cmdlang->location = "cmd_solparm.c(solparm_unlock_mc_done)";
828 goto out;
829 }
830
831 ipmi_cmdlang_out(cmd_info, "SOLPARM unlocked", info->name);
832
833 out:
834 ipmi_cmdlang_unlock(cmd_info);
835 ipmi_solparm_destroy(solparm, NULL, NULL);
836 ipmi_cmdlang_cmd_info_put(cmd_info);
837 ipmi_mem_free(info);
838 }
839
840 static void
solparm_unlock_mc(ipmi_mc_t * mc,void * cb_data)841 solparm_unlock_mc(ipmi_mc_t *mc, void *cb_data)
842 {
843 ipmi_cmd_info_t *cmd_info = cb_data;
844 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
845 int channel;
846 int rv;
847 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
848 int argc = ipmi_cmdlang_get_argc(cmd_info);
849 char **argv = ipmi_cmdlang_get_argv(cmd_info);
850 ipmi_solparm_t *solparm = NULL;
851 solparm_mc_unlock_t *info;
852
853 if ((argc - curr_arg) < 1) {
854 /* Not enough parameters */
855 cmdlang->errstr = "Not enough parameters";
856 cmdlang->err = EINVAL;
857 goto out_err;
858 }
859
860 ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
861 if (cmdlang->err) {
862 cmdlang->errstr = "channel invalid";
863 goto out_err;
864 }
865 curr_arg++;
866
867 rv = ipmi_solparm_alloc(mc, channel, &solparm);
868 if (rv) {
869 cmdlang->errstr = "Error from ipmi_solparm_alloc";
870 cmdlang->err = rv;
871 goto out_err;
872 }
873
874 info = ipmi_mem_alloc(sizeof(*info));
875 if (!info) {
876 cmdlang->errstr = "Out of memory";
877 cmdlang->err = ENOMEM;
878 goto out_err;
879 }
880 info->cmd_info = cmd_info;
881 ipmi_mc_get_name(mc, info->name, sizeof(info->name));
882
883 ipmi_cmdlang_cmd_info_get(cmd_info);
884 rv = ipmi_sol_clear_lock(solparm, NULL, solparm_unlock_mc_done, info);
885 if (rv) {
886 ipmi_cmdlang_cmd_info_put(cmd_info);
887 cmdlang->errstr = "Error from ipmi_sol_clear_lock";
888 cmdlang->err = rv;
889 ipmi_solparm_destroy(solparm, NULL, NULL);
890 ipmi_mem_free(info);
891 goto out_err;
892 }
893 return;
894
895 out_err:
896 if (solparm)
897 ipmi_solparm_destroy(solparm, NULL, NULL);
898 ipmi_mc_get_name(mc, cmdlang->objstr,
899 cmdlang->objstr_len);
900 cmdlang->location = "cmd_solparm.c(solparm_unlock_mc)";
901 }
902
903 static ipmi_cmdlang_cmd_t *solparm_cmds;
904 static ipmi_cmdlang_cmd_t *config_cmds;
905
906 static ipmi_cmdlang_init_t cmds_solparm[] =
907 {
908 { "solparm", NULL,
909 "- Commands dealing with SOL Parameters (solparms)",
910 NULL, NULL, &solparm_cmds},
911 { "list", &solparm_cmds,
912 "- List all the solparms in the system",
913 ipmi_cmdlang_domain_handler, solparm_list, NULL },
914 { "new", &solparm_cmds,
915 "<mc> <channel>"
916 " - Create a solparm for the given MC and channel.",
917 ipmi_cmdlang_mc_handler, solparm_new, NULL },
918 { "info", &solparm_cmds,
919 "<solparm> - Dump information about a solparm",
920 ipmi_cmdlang_solparm_handler, solparm_info, NULL },
921 { "config", &solparm_cmds,
922 "- Commands dealing with SOLPARM configs",
923 NULL, NULL, &config_cmds },
924 { "list", &config_cmds,
925 "- List the sol configurations that currently exist",
926 solparm_config_list, NULL, NULL },
927 { "info", &config_cmds,
928 "<config> - List info on sol configuration",
929 solparm_config_info, NULL, NULL },
930 { "get", &config_cmds,
931 "<solparm> - Fetch the SOL information for the solparm",
932 ipmi_cmdlang_solparm_handler, solparm_config_get, NULL },
933 { "set", &config_cmds,
934 "<solparm> <solparm config> - Set the SOL information for the solparm",
935 ipmi_cmdlang_solparm_handler, solparm_config_set, NULL },
936 { "unlock", &config_cmds,
937 "<solparm> <solparm config> - Unlock, but do not set the config",
938 ipmi_cmdlang_solparm_handler, solparm_config_unlock, NULL },
939 { "update", &config_cmds,
940 "<solparm config> <parm> [selector] <value> - Set the given parameter"
941 " in the solparm config to the given value. If the parameter has"
942 " a selector of some type, the selector must be given, otherwise"
943 " no selector should be given.",
944 solparm_config_update, NULL, NULL },
945 { "close", &config_cmds,
946 "<solparm config> - free the config",
947 solparm_config_close, NULL, NULL },
948 { "unlock_mc", &solparm_cmds,
949 "<mc> <channel> - Unlock the solparms for the given mc/channel",
950 ipmi_cmdlang_mc_handler, solparm_unlock_mc, NULL },
951 { "close", &solparm_cmds,
952 "<solparm> - Close the solparm",
953 ipmi_cmdlang_solparm_handler, solparm_close, NULL },
954 };
955 #define CMDS_SOLPARM_LEN (sizeof(cmds_solparm)/sizeof(ipmi_cmdlang_init_t))
956
957 int
ipmi_cmdlang_solparm_init(os_handler_t * os_hnd)958 ipmi_cmdlang_solparm_init(os_handler_t *os_hnd)
959 {
960 int rv;
961
962 solcs = locked_list_alloc(os_hnd);
963 if (!solcs)
964 return ENOMEM;
965
966 rv = ipmi_cmdlang_reg_table(cmds_solparm, CMDS_SOLPARM_LEN);
967 if (rv) {
968 locked_list_destroy(solcs);
969 solcs = NULL;
970 }
971
972 return rv;
973 }
974
975 static int
config_destroy_handler(void * cb_data,void * item1,void * item2)976 config_destroy_handler(void *cb_data, void *item1, void *item2)
977 {
978 sol_config_info_t *info = item1;
979
980 ipmi_sol_free_config(info->config);
981 ipmi_mem_free(info);
982 return LOCKED_LIST_ITER_CONTINUE;
983 }
984
985 void
ipmi_cmdlang_solparm_shutdown(void)986 ipmi_cmdlang_solparm_shutdown(void)
987 {
988 locked_list_iterate(solcs, config_destroy_handler, NULL);
989 locked_list_destroy(solcs);
990 solcs = NULL;
991 }
992