]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/ntp/libntp/ntp_lineedit.c
Upgrade NTP to 4.2.8p4.
[FreeBSD/releng/10.2.git] / contrib / ntp / libntp / ntp_lineedit.c
1 /*
2  * ntp_lineedit.c - generic interface to various line editing libs
3  */
4 #ifdef HAVE_CONFIG_H
5 # include <config.h>
6 #endif
7
8 #include <errno.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12
13 #if defined(HAVE_READLINE_HISTORY) &&           \
14     (!defined(HAVE_READLINE_HISTORY_H) ||       \
15      !defined(HAVE_READLINE_READLINE_H))
16 # undef HAVE_READLINE_HISTORY
17 #endif
18 #if defined(HAVE_READLINE_HISTORY)
19 # include <readline/readline.h>
20 # include <readline/history.h>
21 # define LE_READLINE
22 #elif defined(HAVE_HISTEDIT_H)
23 # include <histedit.h>
24 # define LE_EDITLINE
25 #else
26 # define LE_NONE
27 #endif
28
29 #include "ntp.h"
30 #include "ntp_stdlib.h"
31 #include "ntp_lineedit.h"
32
33 #define MAXEDITLINE     512
34
35 /*
36  * external references
37  */
38
39 extern char const *     progname;
40
41 /*
42  * globals, private prototypes
43  */
44
45 static int      ntp_readline_initted;
46 static char *   lineedit_prompt;
47
48
49 #ifdef LE_EDITLINE
50 # ifndef H_SETSIZE
51 #  define H_SETSIZE H_EVENT
52 # endif
53 static EditLine *       ntp_el;
54 static History *        ntp_hist;
55 static HistEvent        hev;
56
57 char *  ntp_prompt_callback(EditLine *);
58 #endif  /* LE_EDITLINE */
59
60
61 /*
62  * ntp_readline_init - setup, set or reset prompt string
63  */
64 int
65 ntp_readline_init(
66         const char *    prompt
67         )
68 {
69         int     success;
70
71         success = 1;
72
73         if (prompt) {
74                 if (lineedit_prompt) 
75                         free(lineedit_prompt);
76                 lineedit_prompt = estrdup(prompt);
77         }
78
79 #ifdef LE_EDITLINE
80         if (NULL == ntp_el) {
81
82 # if 4 == EL_INIT_ARGS
83                 ntp_el = el_init(progname, stdin, stdout, stderr);
84 # else
85                 ntp_el = el_init(progname, stdin, stdout);
86 # endif
87                 if (ntp_el) {
88
89                         el_set(ntp_el, EL_PROMPT, ntp_prompt_callback);
90                         el_set(ntp_el, EL_EDITOR, "emacs");
91
92                         ntp_hist = history_init();
93
94                         if (NULL == ntp_hist) {
95
96                                 mfprintf(stderr, "history_init(): %m\n");
97                                 fflush(stderr);
98
99                                 el_end(ntp_el);
100                                 ntp_el = NULL;
101
102                                 success = 0;
103
104                         } else {
105                                 ZERO(hev);
106 #ifdef H_SETSIZE
107                                 history(ntp_hist, &hev, H_SETSIZE, 128);
108 #endif
109                                 el_set(ntp_el, EL_HIST, history,
110                                        ntp_hist);
111                                 /* use any .editrc */
112                                 el_source(ntp_el, NULL);
113                         }
114                 } else
115                         success = 0;
116         }
117 #endif  /* LE_EDITLINE */
118
119         ntp_readline_initted = success;
120
121         return success;
122 }
123
124
125 /*
126  * ntp_readline_uninit - release resources
127  */
128 void
129 ntp_readline_uninit(
130         void
131         )
132 {
133 #ifdef LE_EDITLINE
134         if (ntp_el) {
135                 el_end(ntp_el);
136                 ntp_el = NULL;
137
138                 history_end(ntp_hist);
139                 ntp_hist = NULL;
140         }
141 #endif  /* LE_EDITLINE */
142
143         if (lineedit_prompt) {
144                 free(lineedit_prompt);
145                 lineedit_prompt = NULL;
146         }
147
148         ntp_readline_initted = 0;
149 }
150
151
152 /*
153  * ntp_readline - read a line with the line editor available
154  *
155  * The string returned must be released with free()
156  */
157
158 char *
159 ntp_readline(
160         int *   pcount
161         )
162 {
163         char *          line;
164 #ifdef LE_NONE
165         char            line_buf[MAXEDITLINE];
166 #endif
167 #ifdef LE_EDITLINE
168         const char *    cline;
169 #endif
170
171         if (!ntp_readline_initted)
172                 return NULL;
173
174         *pcount = 0;
175
176 #ifdef LE_READLINE
177         line = readline(lineedit_prompt ? lineedit_prompt : "");
178         if (NULL != line) {
179                 if (*line) {
180                         add_history(line);
181                 }
182                 *pcount = strlen(line);
183         }
184 #endif  /* LE_READLINE */
185
186 #ifdef LE_EDITLINE
187         cline = el_gets(ntp_el, pcount);
188
189         if (NULL != cline) {
190                 history(ntp_hist, &hev, H_ENTER, cline);
191                 line = estrdup(cline);
192         } else if (*pcount == -1) {
193                 line = NULL;
194         } else {
195                 line = estrdup("");
196         }
197 #endif  /* LE_EDITLINE */
198
199 #ifdef LE_NONE
200                                         /* stone hammers */
201         if (lineedit_prompt) {
202 # ifdef VMS
203                         /*
204                          * work around problem mixing
205                          * stdout & stderr
206                          */
207                         fputs("", stdout);
208 # endif /* VMS */
209
210                 fputs(lineedit_prompt, stderr);
211                 fflush(stderr);
212         }
213
214         line = fgets(line_buf, sizeof(line_buf), stdin);
215         if (NULL != line && *line) {
216                 *pcount = strlen(line);
217                 line = estrdup(line);
218         } else
219                 line = NULL;
220
221 #endif  /* LE_NONE */
222
223
224         if (!line)                      /* EOF */
225                 fputs("\n", stderr);
226
227         return line;
228 }
229
230
231 #ifdef LE_EDITLINE
232 /*
233  * ntp_prompt_callback - return prompt string to el_gets()
234  */
235 char *
236 ntp_prompt_callback(
237         EditLine *el
238         )
239 {
240         UNUSED_ARG(el);
241
242         return lineedit_prompt;
243 }
244 #endif /* LE_EDITLINE */
245