]> git.proxmox.com Git - mirror_frr.git/blame - lib/vty.h
*: make consistent & update GPLv2 file headers
[mirror_frr.git] / lib / vty.h
CommitLineData
718e3744 1/* Virtual terminal [aka TeletYpe] interface routine
896014f4
DL
2 * Copyright (C) 1997 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
718e3744 20
21#ifndef _ZEBRA_VTY_H
22#define _ZEBRA_VTY_H
23
b21b19c5 24#include "thread.h"
1ed72e0b 25#include "log.h"
d227617a 26#include "sockunion.h"
0878c8d4 27#include "qobj.h"
b21b19c5 28
2af38873 29#define VTY_BUFSIZ 4096
718e3744 30#define VTY_MAXHIST 20
31
32/* VTY struct. */
33struct vty
34{
35 /* File descripter of this vty. */
36 int fd;
37
c5e69a02
DL
38 /* output FD, to support stdin/stdout combination */
39 int wfd;
40
718e3744 41 /* Is this vty connect to file or not */
42 enum {VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV} type;
43
44 /* Node status of this vty */
45 int node;
46
718e3744 47 /* Failure count */
48 int fail;
49
50 /* Output buffer. */
51 struct buffer *obuf;
52
53 /* Command input buffer */
54 char *buf;
55
5689fe5f
DW
56 /* Command input error buffer */
57 char *error_buf;
58
718e3744 59 /* Command cursor point */
60 int cp;
61
62 /* Command length */
63 int length;
64
65 /* Command max length. */
66 int max;
67
68 /* Histry of command */
69 char *hist[VTY_MAXHIST];
70
71 /* History lookup current point */
72 int hp;
73
74 /* History insert end point */
75 int hindex;
76
0878c8d4
DL
77 /* qobj object ID (replacement for "index") */
78 uint64_t qobj_index;
718e3744 79
6a098b3a
DL
80 /* qobj second-level object ID (replacement for "index_sub") */
81 uint64_t qobj_index_sub;
718e3744 82
83 /* For escape character. */
84 unsigned char escape;
85
86 /* Current vty status. */
5a646650 87 enum {VTY_NORMAL, VTY_CLOSE, VTY_MORE, VTY_MORELINE} status;
718e3744 88
9fc7ebf1 89 /* IAC handling: was the last character received the
90 IAC (interpret-as-command) escape character (and therefore the next
91 character will be the command code)? Refer to Telnet RFC 854. */
718e3744 92 unsigned char iac;
93
9fc7ebf1 94 /* IAC SB (option subnegotiation) handling */
718e3744 95 unsigned char iac_sb_in_progress;
9fc7ebf1 96 /* At the moment, we care only about the NAWS (window size) negotiation,
97 and that requires just a 5-character buffer (RFC 1073):
98 <NAWS char> <16-bit width> <16-bit height> */
99#define TELNET_NAWS_SB_LEN 5
100 unsigned char sb_buf[TELNET_NAWS_SB_LEN];
101 /* How many subnegotiation characters have we received? We just drop
102 those that do not fit in the buffer. */
103 size_t sb_len;
718e3744 104
105 /* Window width/height. */
106 int width;
107 int height;
108
718e3744 109 /* Configure lines. */
110 int lines;
111
718e3744 112 /* Terminal monitor. */
113 int monitor;
114
115 /* In configure mode. */
116 int config;
117
118 /* Read and write thread. */
119 struct thread *t_read;
120 struct thread *t_write;
121
122 /* Timeout seconds and thread. */
123 unsigned long v_timeout;
124 struct thread *t_timeout;
d227617a
JBD
125
126 /* What address is this vty comming from. */
127 char address[SU_ADDRSTRLEN];
718e3744 128};
129
0878c8d4 130static inline void vty_push_context(struct vty *vty,
a50b7ceb 131 int node, uint64_t id)
0878c8d4
DL
132{
133 vty->node = node;
134 vty->qobj_index = id;
0878c8d4
DL
135}
136
3c5070be
DL
137/* note: VTY_PUSH_CONTEXT(..., NULL) doesn't work, since it will try to
138 * dereference "NULL->qobj_node.nid" */
0878c8d4 139#define VTY_PUSH_CONTEXT(nodeval, ptr) \
a50b7ceb 140 vty_push_context(vty, nodeval, QOBJ_ID_0SAFE(ptr))
3c5070be 141#define VTY_PUSH_CONTEXT_NULL(nodeval) \
a50b7ceb 142 vty_push_context(vty, nodeval, 0ULL)
6a098b3a
DL
143#define VTY_PUSH_CONTEXT_SUB(nodeval, ptr) do { \
144 vty->node = nodeval; \
145 /* qobj_index stays untouched */ \
3c5070be 146 vty->qobj_index_sub = QOBJ_ID_0SAFE(ptr); \
6a098b3a 147 } while (0)
0878c8d4
DL
148
149/* can return NULL if context is invalid! */
150#define VTY_GET_CONTEXT(structname) \
151 QOBJ_GET_TYPESAFE(vty->qobj_index, structname)
6a098b3a
DL
152#define VTY_GET_CONTEXT_SUB(structname) \
153 QOBJ_GET_TYPESAFE(vty->qobj_index_sub, structname)
0878c8d4
DL
154
155/* will return if ptr is NULL. */
156#define VTY_CHECK_CONTEXT(ptr) \
157 if (!ptr) { \
158 vty_out (vty, "Current configuration object was deleted " \
159 "by another process.%s", VTY_NEWLINE); \
160 return CMD_WARNING; \
161 }
162
163/* struct structname *ptr = <context>; ptr will never be NULL. */
164#define VTY_DECLVAR_CONTEXT(structname, ptr) \
165 struct structname *ptr = VTY_GET_CONTEXT(structname); \
166 VTY_CHECK_CONTEXT(ptr);
6a098b3a
DL
167#define VTY_DECLVAR_CONTEXT_SUB(structname, ptr) \
168 struct structname *ptr = VTY_GET_CONTEXT_SUB(structname); \
169 VTY_CHECK_CONTEXT(ptr);
0878c8d4 170
eac6e3f0
RW
171struct vty_arg
172{
173 const char *name;
174 const char *value;
175 const char **argv;
176 int argc;
177};
178
718e3744 179/* Integrated configuration file. */
e20dc2ba 180#define INTEGRATE_DEFAULT_CONFIG "frr.conf"
718e3744 181
182/* Small macro to determine newline is newline only or linefeed needed. */
183#define VTY_NEWLINE ((vty->type == VTY_TERM) ? "\r\n" : "\n")
184
185/* Default time out value */
186#define VTY_TIMEOUT_DEFAULT 600
187
188/* Vty read buffer size. */
189#define VTY_READ_BUFSIZ 512
190
191/* Directory separator. */
192#ifndef DIRECTORY_SEP
193#define DIRECTORY_SEP '/'
194#endif /* DIRECTORY_SEP */
195
196#ifndef IS_DIRECTORY_SEP
197#define IS_DIRECTORY_SEP(c) ((c) == DIRECTORY_SEP)
198#endif
199
200/* GCC have printf type attribute check. */
201#ifdef __GNUC__
202#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
203#else
204#define PRINTF_ATTRIBUTE(a,b)
205#endif /* __GNUC__ */
206
7798b632
AC
207/* Utility macros to convert VTY argument to unsigned long */
208#define VTY_GET_ULONG(NAME,V,STR) \
d4f0960c 209do { \
42d49865 210 char *endptr = NULL; \
664711c1 211 errno = 0; \
42d49865 212 (V) = strtoul ((STR), &endptr, 10); \
813d4307 213 if (*(STR) == '-') \
42d49865 214 { \
813d4307
DW
215 vty_out (vty, "%% Invalid %s value (dash)%s", NAME, VTY_NEWLINE); \
216 return CMD_WARNING; \
217 } \
218 if (*endptr != '\0') \
219 { \
220 vty_out (vty, "%% Invalid %s value (%s)%s", NAME, endptr, VTY_NEWLINE); \
221 return CMD_WARNING; \
222 } \
223 if (errno) \
224 { \
225 vty_out (vty, "%% Invalid %s value (error %d)%s", NAME, errno, VTY_NEWLINE); \
42d49865 226 return CMD_WARNING; \
227 } \
d4f0960c 228} while (0)
718e3744 229
8fe8a7f6
DS
230/* Utility macros to convert VTY argument to unsigned long long */
231#define VTY_GET_ULL(NAME,V,STR) \
232do { \
233 char *endptr = NULL; \
234 errno = 0; \
235 (V) = strtoull ((STR), &endptr, 10); \
813d4307
DW
236 if (*(STR) == '-') \
237 { \
238 vty_out (vty, "%% Invalid %s value (dash)%s", NAME, VTY_NEWLINE); \
239 return CMD_WARNING; \
240 } \
241 if (*endptr != '\0') \
242 { \
243 vty_out (vty, "%% Invalid %s value (%s)%s", NAME, endptr, VTY_NEWLINE); \
244 return CMD_WARNING; \
245 } \
246 if (errno) \
8fe8a7f6 247 { \
813d4307 248 vty_out (vty, "%% Invalid %s value (error %d)%s", NAME, errno, VTY_NEWLINE); \
8fe8a7f6
DS
249 return CMD_WARNING; \
250 } \
251} while (0)
252
7798b632
AC
253/*
254 * The logic below ((TMPL) <= ((MIN) && (TMPL) != (MIN)) is
255 * done to circumvent the compiler complaining about
256 * comparing unsigned numbers against zero, if MIN is zero.
257 * NB: The compiler isn't smart enough to supress the warning
258 * if you write (MIN) != 0 && tmpl < (MIN).
259 */
260#define VTY_GET_INTEGER_RANGE_HEART(NAME,TMPL,STR,MIN,MAX) \
261do { \
262 VTY_GET_ULONG(NAME, (TMPL), STR); \
263 if ( ((TMPL) <= (MIN) && (TMPL) != (MIN)) || (TMPL) > (MAX) ) \
264 { \
265 vty_out (vty, "%% Invalid %s value%s", NAME, VTY_NEWLINE);\
266 return CMD_WARNING; \
267 } \
268} while (0)
269
270#define VTY_GET_INTEGER_RANGE(NAME,V,STR,MIN,MAX) \
271do { \
c152e0c1 272 unsigned long long tmpl; \
7798b632
AC
273 VTY_GET_INTEGER_RANGE_HEART(NAME,tmpl,STR,MIN,MAX); \
274 (V) = tmpl; \
275} while (0)
276
277#define VTY_CHECK_INTEGER_RANGE(NAME,STR,MIN,MAX) \
278do { \
279 unsigned long tmpl; \
280 VTY_GET_INTEGER_RANGE_HEART(NAME,tmpl,STR,MIN,MAX); \
d4f0960c 281} while (0)
718e3744 282
7798b632
AC
283#define VTY_GET_INTEGER(NAME,V,STR) \
284 VTY_GET_INTEGER_RANGE(NAME,V,STR,0U,UINT32_MAX)
42d49865 285
8cc4198f 286#define VTY_GET_IPV4_ADDRESS(NAME,V,STR) \
d4f0960c 287do { \
8cc4198f 288 int retv; \
289 retv = inet_aton ((STR), &(V)); \
290 if (!retv) \
291 { \
292 vty_out (vty, "%% Invalid %s value%s", NAME, VTY_NEWLINE); \
293 return CMD_WARNING; \
294 } \
d4f0960c 295} while (0)
8cc4198f 296
297#define VTY_GET_IPV4_PREFIX(NAME,V,STR) \
d4f0960c 298do { \
8cc4198f 299 int retv; \
300 retv = str2prefix_ipv4 ((STR), &(V)); \
301 if (retv <= 0) \
302 { \
303 vty_out (vty, "%% Invalid %s value%s", NAME, VTY_NEWLINE); \
304 return CMD_WARNING; \
305 } \
d4f0960c 306} while (0)
8cc4198f 307
0b0668e6
DL
308#define VTY_WARN_EXPERIMENTAL() \
309do { \
310 vty_out (vty, "%% WARNING: this command is experimental. Both its name and" \
311 " parameters may%s%% change in a future version of Quagga," \
312 " possibly breaking your configuration!%s", \
313 VTY_NEWLINE, VTY_NEWLINE); \
314} while (0)
315
718e3744 316/* Exported variables */
317extern char integrate_default[];
318
319/* Prototypes. */
8cc4198f 320extern void vty_init (struct thread_master *);
321extern void vty_init_vtysh (void);
228da428 322extern void vty_terminate (void);
8cc4198f 323extern void vty_reset (void);
324extern struct vty *vty_new (void);
dbf78092 325extern struct vty *vty_stdio (void (*atclose)(void));
8cc4198f 326extern int vty_out (struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3);
eb05883f 327extern void vty_read_config (const char *, char *);
8cc4198f 328extern void vty_time_print (struct vty *, int);
329extern void vty_serv_sock (const char *, unsigned short, const char *);
330extern void vty_close (struct vty *);
331extern char *vty_get_cwd (void);
332extern void vty_log (const char *level, const char *proto,
1ed72e0b 333 const char *fmt, struct timestamp_control *, va_list);
8cc4198f 334extern int vty_config_lock (struct vty *);
335extern int vty_config_unlock (struct vty *);
cc933ef9 336extern void vty_config_lockless (void);
8cc4198f 337extern int vty_shell (struct vty *);
338extern int vty_shell_serv (struct vty *);
339extern void vty_hello (struct vty *);
718e3744 340
274a4a44 341/* Send a fixed-size message to all vty terminal monitors; this should be
342 an async-signal-safe function. */
24873f0c 343extern void vty_log_fixed (char *buf, size_t len);
274a4a44 344
eac6e3f0
RW
345extern const char *vty_get_arg_value (struct vty_arg **, const char *);
346extern struct vty_arg *vty_get_arg (struct vty_arg **, const char *);
347
718e3744 348#endif /* _ZEBRA_VTY_H */