~ubuntu-branches/ubuntu/vivid/openipmi/vivid

« back to all changes in this revision

Viewing changes to libedit/el.c

  • Committer: Bazaar Package Importer
  • Author(s): Noèl Köthe
  • Date: 2006-09-15 17:56:24 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 etch)
  • Revision ID: james.westby@ubuntu.com-20060915175624-ljk0mg3xtcm65tvm
Tags: 2.0.7-1
* new upstream release from 2006-06-08
  Thanks to John Wright <john.wright hp.com> for initial work
  (closes: Bug#380149)
* updated Standards Version
* new binaries openipmicmd, openipmish, rmcp_ping

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*      $NetBSD: el.c,v 1.41 2005/08/19 04:21:47 christos Exp $ */
 
2
 
 
3
/*-
 
4
 * Copyright (c) 1992, 1993
 
5
 *      The Regents of the University of California.  All rights reserved.
 
6
 *
 
7
 * This code is derived from software contributed to Berkeley by
 
8
 * Christos Zoulas of Cornell University.
 
9
 *
 
10
 * Redistribution and use in source and binary forms, with or without
 
11
 * modification, are permitted provided that the following conditions
 
12
 * are met:
 
13
 * 1. Redistributions of source code must retain the above copyright
 
14
 *    notice, this list of conditions and the following disclaimer.
 
15
 * 2. Redistributions in binary form must reproduce the above copyright
 
16
 *    notice, this list of conditions and the following disclaimer in the
 
17
 *    documentation and/or other materials provided with the distribution.
 
18
 * 3. Neither the name of the University nor the names of its contributors
 
19
 *    may be used to endorse or promote products derived from this software
 
20
 *    without specific prior written permission.
 
21
 *
 
22
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 
23
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
24
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
25
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
26
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
27
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
28
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
29
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
31
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
32
 * SUCH DAMAGE.
 
33
 */
 
34
 
 
35
#include "sys.h"
 
36
#if !defined(lint) && !defined(SCCSID)
 
37
#if 0
 
38
static char sccsid[] = "@(#)el.c        8.2 (Berkeley) 1/3/94";
 
39
#else
 
40
__RCSID("$NetBSD: el.c,v 1.41 2005/08/19 04:21:47 christos Exp $");
 
41
#endif
 
42
#endif /* not lint && not SCCSID */
 
43
 
 
44
/*
 
45
 * el.c: EditLine interface functions
 
46
 */
 
47
#include <sys/types.h>
 
48
#include <sys/param.h>
 
49
#include <string.h>
 
50
#include <stdlib.h>
 
51
#include <stdarg.h>
 
52
#include "el.h"
 
53
 
 
54
/* el_init():
 
55
 *      Initialize editline and set default parameters.
 
56
 */
 
57
public EditLine *
 
58
el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
 
59
{
 
60
 
 
61
        EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
 
62
 
 
63
        if (el == NULL)
 
64
                return (NULL);
 
65
 
 
66
        memset(el, 0, sizeof(EditLine));
 
67
 
 
68
        el->el_infd = fileno(fin);
 
69
        el->el_outfile = fout;
 
70
        el->el_errfile = ferr;
 
71
        if ((el->el_prog = el_strdup(prog)) == NULL) {
 
72
                el_free(el);
 
73
                return NULL;
 
74
        }
 
75
 
 
76
        /*
 
77
         * Initialize all the modules. Order is important!!!
 
78
         */
 
79
        el->el_flags = 0;
 
80
 
 
81
        if (term_init(el) == -1) {
 
82
                el_free(el->el_prog);
 
83
                el_free(el);
 
84
                return NULL;
 
85
        }
 
86
        (void) key_init(el);
 
87
        (void) map_init(el);
 
88
        if (tty_init(el) == -1)
 
89
                el->el_flags |= NO_TTY;
 
90
        (void) ch_init(el);
 
91
        (void) search_init(el);
 
92
        (void) hist_init(el);
 
93
        (void) prompt_init(el);
 
94
        (void) sig_init(el);
 
95
        (void) read_init(el);
 
96
 
 
97
        return (el);
 
98
}
 
99
 
 
100
 
 
101
/* el_end():
 
102
 *      Clean up.
 
103
 */
 
104
public void
 
105
el_end(EditLine *el)
 
106
{
 
107
 
 
108
        if (el == NULL)
 
109
                return;
 
110
 
 
111
        el_reset(el);
 
112
 
 
113
        term_end(el);
 
114
        key_end(el);
 
115
        map_end(el);
 
116
        tty_end(el);
 
117
        ch_end(el);
 
118
        search_end(el);
 
119
        hist_end(el);
 
120
        prompt_end(el);
 
121
        sig_end(el);
 
122
 
 
123
        el_free((ptr_t) el->el_prog);
 
124
        el_free((ptr_t) el);
 
125
}
 
126
 
 
127
 
 
128
/* el_reset():
 
129
 *      Reset the tty and the parser
 
130
 */
 
131
public void
 
132
el_reset(EditLine *el)
 
133
{
 
134
 
 
135
        tty_cookedmode(el);
 
136
        ch_reset(el, 0);                /* XXX: Do we want that? */
 
137
}
 
138
 
 
139
 
 
140
/* el_set():
 
141
 *      set the editline parameters
 
142
 */
 
143
public int
 
144
el_set(EditLine *el, int op, ...)
 
145
{
 
146
        va_list va;
 
147
        int rv = 0;
 
148
 
 
149
        if (el == NULL)
 
150
                return (-1);
 
151
        va_start(va, op);
 
152
 
 
153
        switch (op) {
 
154
        case EL_PROMPT:
 
155
        case EL_RPROMPT:
 
156
                rv = prompt_set(el, va_arg(va, el_pfunc_t), op);
 
157
                break;
 
158
 
 
159
        case EL_TERMINAL:
 
160
                rv = term_set(el, va_arg(va, char *));
 
161
                break;
 
162
 
 
163
        case EL_EDITOR:
 
164
                rv = map_set_editor(el, va_arg(va, char *));
 
165
                break;
 
166
 
 
167
        case EL_SIGNAL:
 
168
                if (va_arg(va, int))
 
169
                        el->el_flags |= HANDLE_SIGNALS;
 
170
                else
 
171
                        el->el_flags &= ~HANDLE_SIGNALS;
 
172
                break;
 
173
 
 
174
        case EL_BIND:
 
175
        case EL_TELLTC:
 
176
        case EL_SETTC:
 
177
        case EL_ECHOTC:
 
178
        case EL_SETTY:
 
179
        {
 
180
                const char *argv[20];
 
181
                int i;
 
182
 
 
183
                for (i = 1; i < 20; i++)
 
184
                        if ((argv[i] = va_arg(va, char *)) == NULL)
 
185
                                break;
 
186
 
 
187
                switch (op) {
 
188
                case EL_BIND:
 
189
                        argv[0] = "bind";
 
190
                        rv = map_bind(el, i, argv);
 
191
                        break;
 
192
 
 
193
                case EL_TELLTC:
 
194
                        argv[0] = "telltc";
 
195
                        rv = term_telltc(el, i, argv);
 
196
                        break;
 
197
 
 
198
                case EL_SETTC:
 
199
                        argv[0] = "settc";
 
200
                        rv = term_settc(el, i, argv);
 
201
                        break;
 
202
 
 
203
                case EL_ECHOTC:
 
204
                        argv[0] = "echotc";
 
205
                        rv = term_echotc(el, i, argv);
 
206
                        break;
 
207
 
 
208
                case EL_SETTY:
 
209
                        argv[0] = "setty";
 
210
                        rv = tty_stty(el, i, argv);
 
211
                        break;
 
212
 
 
213
                default:
 
214
                        rv = -1;
 
215
                        EL_ABORT((el->el_errfile, "Bad op %d\n", op));
 
216
                        break;
 
217
                }
 
218
                break;
 
219
        }
 
220
 
 
221
        case EL_ADDFN:
 
222
        {
 
223
                char *name = va_arg(va, char *);
 
224
                char *help = va_arg(va, char *);
 
225
                el_func_t func = va_arg(va, el_func_t);
 
226
 
 
227
                rv = map_addfunc(el, name, help, func);
 
228
                break;
 
229
        }
 
230
 
 
231
        case EL_HIST:
 
232
        {
 
233
                hist_fun_t func = va_arg(va, hist_fun_t);
 
234
                ptr_t ptr = va_arg(va, char *);
 
235
 
 
236
                rv = hist_set(el, func, ptr);
 
237
                break;
 
238
        }
 
239
 
 
240
        case EL_EDITMODE:
 
241
                if (va_arg(va, int))
 
242
                        el->el_flags &= ~EDIT_DISABLED;
 
243
                else
 
244
                        el->el_flags |= EDIT_DISABLED;
 
245
                rv = 0;
 
246
                break;
 
247
 
 
248
        case EL_GETCFN:
 
249
        {
 
250
                el_rfunc_t rc = va_arg(va, el_rfunc_t);
 
251
                rv = el_read_setfn(el, rc);
 
252
                break;
 
253
        }
 
254
 
 
255
        case EL_CLIENTDATA:
 
256
                el->el_data = va_arg(va, void *);
 
257
                break;
 
258
 
 
259
        case EL_UNBUFFERED:
 
260
                rv = va_arg(va, int);
 
261
                if (rv && !(el->el_flags & UNBUFFERED)) {
 
262
                        el->el_flags |= UNBUFFERED;
 
263
                        read_prepare(el);
 
264
                } else if (!rv && (el->el_flags & UNBUFFERED)) {
 
265
                        el->el_flags &= ~UNBUFFERED;
 
266
                        read_finish(el);
 
267
                }
 
268
                rv = 0;
 
269
                break;
 
270
 
 
271
        case EL_PREP_TERM:
 
272
                rv = va_arg(va, int);
 
273
                if (rv)
 
274
                        (void) tty_rawmode(el);
 
275
                else
 
276
                        (void) tty_cookedmode(el);
 
277
                rv = 0;
 
278
                break;
 
279
 
 
280
        default:
 
281
                rv = -1;
 
282
                break;
 
283
        }
 
284
 
 
285
        va_end(va);
 
286
        return (rv);
 
287
}
 
288
 
 
289
 
 
290
/* el_get():
 
291
 *      retrieve the editline parameters
 
292
 */
 
293
public int
 
294
el_get(EditLine *el, int op, void *ret)
 
295
{
 
296
        int rv;
 
297
 
 
298
        if (el == NULL || ret == NULL)
 
299
                return (-1);
 
300
        switch (op) {
 
301
        case EL_PROMPT:
 
302
        case EL_RPROMPT:
 
303
                rv = prompt_get(el, (el_pfunc_t *) ret, op);
 
304
                break;
 
305
 
 
306
        case EL_EDITOR:
 
307
                rv = map_get_editor(el, (const char **)ret);
 
308
                break;
 
309
 
 
310
        case EL_SIGNAL:
 
311
                *((int *) ret) = (el->el_flags & HANDLE_SIGNALS);
 
312
                rv = 0;
 
313
                break;
 
314
 
 
315
        case EL_EDITMODE:
 
316
                *((int *) ret) = (!(el->el_flags & EDIT_DISABLED));
 
317
                rv = 0;
 
318
                break;
 
319
 
 
320
        case EL_TERMINAL:
 
321
                term_get(el, (const char **)ret);
 
322
                rv = 0;
 
323
                break;
 
324
 
 
325
#if 0                           /* XXX */
 
326
        case EL_BIND:
 
327
        case EL_TELLTC:
 
328
        case EL_SETTC:
 
329
        case EL_ECHOTC:
 
330
        case EL_SETTY:
 
331
        {
 
332
                const char *argv[20];
 
333
                int i;
 
334
 
 
335
                for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++)
 
336
                        if ((argv[i] = va_arg(va, char *)) == NULL)
 
337
                                break;
 
338
 
 
339
                switch (op) {
 
340
                case EL_BIND:
 
341
                        argv[0] = "bind";
 
342
                        rv = map_bind(el, i, argv);
 
343
                        break;
 
344
 
 
345
                case EL_TELLTC:
 
346
                        argv[0] = "telltc";
 
347
                        rv = term_telltc(el, i, argv);
 
348
                        break;
 
349
 
 
350
                case EL_SETTC:
 
351
                        argv[0] = "settc";
 
352
                        rv = term_settc(el, i, argv);
 
353
                        break;
 
354
 
 
355
                case EL_ECHOTC:
 
356
                        argv[0] = "echotc";
 
357
                        rv = term_echotc(el, i, argv);
 
358
                        break;
 
359
 
 
360
                case EL_SETTY:
 
361
                        argv[0] = "setty";
 
362
                        rv = tty_stty(el, i, argv);
 
363
                        break;
 
364
 
 
365
                default:
 
366
                        rv = -1;
 
367
                        EL_ABORT((el->errfile, "Bad op %d\n", op));
 
368
                        break;
 
369
                }
 
370
                break;
 
371
        }
 
372
 
 
373
        case EL_ADDFN:
 
374
        {
 
375
                char *name = va_arg(va, char *);
 
376
                char *help = va_arg(va, char *);
 
377
                el_func_t func = va_arg(va, el_func_t);
 
378
 
 
379
                rv = map_addfunc(el, name, help, func);
 
380
                break;
 
381
        }
 
382
 
 
383
        case EL_HIST:
 
384
                {
 
385
                        hist_fun_t func = va_arg(va, hist_fun_t);
 
386
                        ptr_t ptr = va_arg(va, char *);
 
387
                        rv = hist_set(el, func, ptr);
 
388
                }
 
389
                break;
 
390
#endif /* XXX */
 
391
 
 
392
        case EL_GETCFN:
 
393
                *((el_rfunc_t *)ret) = el_read_getfn(el);
 
394
                rv = 0;
 
395
                break;
 
396
 
 
397
        case EL_CLIENTDATA:
 
398
                *((void **)ret) = el->el_data;
 
399
                rv = 0;
 
400
                break;
 
401
 
 
402
        case EL_UNBUFFERED:
 
403
                *((int *) ret) = (!(el->el_flags & UNBUFFERED));
 
404
                rv = 0;
 
405
                break;
 
406
 
 
407
        default:
 
408
                rv = -1;
 
409
        }
 
410
 
 
411
        return (rv);
 
412
}
 
413
 
 
414
 
 
415
/* el_line():
 
416
 *      Return editing info
 
417
 */
 
418
public const LineInfo *
 
419
el_line(EditLine *el)
 
420
{
 
421
 
 
422
        return (const LineInfo *) (void *) &el->el_line;
 
423
}
 
424
 
 
425
 
 
426
/* el_source():
 
427
 *      Source a file
 
428
 */
 
429
public int
 
430
el_source(EditLine *el, const char *fname)
 
431
{
 
432
        FILE *fp;
 
433
        size_t len;
 
434
        char *ptr;
 
435
 
 
436
        fp = NULL;
 
437
        if (fname == NULL) {
 
438
                static const char elpath[] = "/.editrc";
 
439
#ifdef MAXPATHLEN
 
440
                char path[MAXPATHLEN];
 
441
#else
 
442
                char path[4096];
 
443
#endif
 
444
 
 
445
#ifdef HAVE_ISSETUGID
 
446
                if (issetugid())
 
447
                        return (-1);
 
448
#endif
 
449
                if ((ptr = getenv("HOME")) == NULL)
 
450
                        return (-1);
 
451
                if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
 
452
                        return (-1);
 
453
                if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
 
454
                        return (-1);
 
455
                fname = path;
 
456
        }
 
457
        if (fp == NULL)
 
458
                fp = fopen(fname, "r");
 
459
        if (fp == NULL)
 
460
                return (-1);
 
461
 
 
462
        while ((ptr = fgetln(fp, &len)) != NULL) {
 
463
                if (len > 0 && ptr[len - 1] == '\n')
 
464
                        --len;
 
465
                ptr[len] = '\0';
 
466
                if (parse_line(el, ptr) == -1) {
 
467
                        (void) fclose(fp);
 
468
                        return (-1);
 
469
                }
 
470
        }
 
471
 
 
472
        (void) fclose(fp);
 
473
        return (0);
 
474
}
 
475
 
 
476
 
 
477
/* el_resize():
 
478
 *      Called from program when terminal is resized
 
479
 */
 
480
public void
 
481
el_resize(EditLine *el)
 
482
{
 
483
        int lins, cols;
 
484
        sigset_t oset, nset;
 
485
 
 
486
        (void) sigemptyset(&nset);
 
487
        (void) sigaddset(&nset, SIGWINCH);
 
488
        (void) sigprocmask(SIG_BLOCK, &nset, &oset);
 
489
 
 
490
        /* get the correct window size */
 
491
        if (term_get_size(el, &lins, &cols))
 
492
                term_change_size(el, lins, cols);
 
493
 
 
494
        (void) sigprocmask(SIG_SETMASK, &oset, NULL);
 
495
}
 
496
 
 
497
 
 
498
/* el_beep():
 
499
 *      Called from the program to beep
 
500
 */
 
501
public void
 
502
el_beep(EditLine *el)
 
503
{
 
504
 
 
505
        term_beep(el);
 
506
}
 
507
 
 
508
 
 
509
/* el_editmode()
 
510
 *      Set the state of EDIT_DISABLED from the `edit' command.
 
511
 */
 
512
protected int
 
513
/*ARGSUSED*/
 
514
el_editmode(EditLine *el, int argc, const char **argv)
 
515
{
 
516
        const char *how;
 
517
 
 
518
        if (argv == NULL || argc != 2 || argv[1] == NULL)
 
519
                return (-1);
 
520
 
 
521
        how = argv[1];
 
522
        if (strcmp(how, "on") == 0) {
 
523
                el->el_flags &= ~EDIT_DISABLED;
 
524
                tty_rawmode(el);
 
525
        } else if (strcmp(how, "off") == 0) {
 
526
                tty_cookedmode(el);
 
527
                el->el_flags |= EDIT_DISABLED;
 
528
        }
 
529
        else {
 
530
                (void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
 
531
                return (-1);
 
532
        }
 
533
        return (0);
 
534
}