summaryrefslogtreecommitdiffstats
path: root/include/osmocom/vty/vty.h
blob: 1dcc230003458b18524b144d1cf1553727ab5f61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#pragma once

#include <stdio.h>
#include <stdarg.h>

/*! \defgroup vty VTY (Virtual TTY) interface
 *  @{
 */
/*! \file vty.h */

/* GCC have printf type attribute check.  */
#ifdef __GNUC__
#define VTY_PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
#else
#define VTY_PRINTF_ATTRIBUTE(a,b)
#endif				/* __GNUC__ */

/* Does the I/O error indicate that the operation should be retried later? */
#define ERRNO_IO_RETRY(EN) \
	(((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))

/* Vty read buffer size. */
#define VTY_READ_BUFSIZ 512

#define VTY_BUFSIZ 512
#define VTY_MAXHIST 20

/*! \brief VTY events */
enum event {
	VTY_SERV,
	VTY_READ,
	VTY_WRITE,
	VTY_CLOSED,
	VTY_TIMEOUT_RESET,
#ifdef VTYSH
	VTYSH_SERV,
	VTYSH_READ,
	VTYSH_WRITE
#endif				/* VTYSH */
};

enum vty_type {
	VTY_TERM,
	VTY_FILE,
	VTY_SHELL,
	VTY_SHELL_SERV
};

/*! Internal representation of a single VTY */
struct vty {
	/*! \brief underlying file (if any) */
	FILE *file;

	/*! \brief private data, specified by creator */
	void *priv;

	/*! \brief File descripter of this vty. */
	int fd;

	/*! \brief Is this vty connect to file or not */
	enum vty_type type;

	/*! \brief Node status of this vty */
	int node;

	/*! \brief Failure count */
	int fail;

	/*! \brief Output buffer. */
	struct buffer *obuf;

	/*! \brief Command input buffer */
	char *buf;

	/*! \brief Command cursor point */
	int cp;

	/*! \brief Command length */
	int length;

	/*! \brief Command max length. */
	int max;

	/*! \brief Histry of command */
	char *hist[VTY_MAXHIST];

	/*! \brief History lookup current point */
	int hp;

	/*! \brief History insert end point */
	int hindex;

	/*! \brief For current referencing point of interface, route-map,
	   access-list etc... */
	void *index;

	/*! \brief For multiple level index treatment such as key chain and key. */
	void *index_sub;

	/*! \brief For escape character. */
	unsigned char escape;

	/*! \brief Current vty status. */
	enum { VTY_NORMAL, VTY_CLOSE, VTY_MORE, VTY_MORELINE } status;

	/*! \brief IAC handling
	 *
	 * IAC handling: was the last character received the IAC
	 * (interpret-as-command) escape character (and therefore the next
	 * character will be the command code)?  Refer to Telnet RFC 854. */
	unsigned char iac;

	/*! \brief IAC SB (option subnegotiation) handling */
	unsigned char iac_sb_in_progress;
	/* At the moment, we care only about the NAWS (window size) negotiation,
	 * and that requires just a 5-character buffer (RFC 1073):
	 * <NAWS char> <16-bit width> <16-bit height> */
#define TELNET_NAWS_SB_LEN 5
	/*! \brief sub-negotiation buffer */
	unsigned char sb_buf[TELNET_NAWS_SB_LEN];
	/*! \brief How many subnegotiation characters have we received?  
	 *
	 * We just drop those that do not fit in the buffer. */
	size_t sb_len;

	/*! \brief Window width */
	int width;
	/*! \brief Widnow height */
	int height;

	/*! \brief Configure lines. */
	int lines;

	int monitor;

	/*! \brief In configure mode. */
	int config;
};

/* Small macro to determine newline is newline only or linefeed needed. */
#define VTY_NEWLINE  ((vty->type == VTY_TERM) ? "\r\n" : "\n")

static inline const char *vty_newline(struct vty *vty)
{
	return VTY_NEWLINE;
}

/*! Information an application registers with the VTY */
struct vty_app_info {
	/*! \brief name of the application */
	const char *name;
	/*! \brief version string of the application */
	const char *version;
	/*! \brief copyright string of the application */
	const char *copyright;
	/*! \brief \ref talloc context */
	void *tall_ctx;
	/*! \brief call-back for returning to parent n ode */
	enum node_type (*go_parent_cb)(struct vty *vty);
	/*! \brief call-back to determine if node is config node */
	int (*is_config_node)(struct vty *vty, int node);
	/*! \brief Check if the config is consistent before write */
	int (*config_is_consistent)(struct vty *vty);
};

/* Prototypes. */
void vty_init(struct vty_app_info *app_info);
int vty_read_config_file(const char *file_name, void *priv);
void vty_init_vtysh (void);
void vty_reset (void);
struct vty *vty_new (void);
struct vty *vty_create (int vty_sock, void *priv);
int vty_out (struct vty *, const char *, ...) VTY_PRINTF_ATTRIBUTE(2, 3);
int vty_out_newline(struct vty *);
int vty_read(struct vty *vty);
//void vty_time_print (struct vty *, int);
void vty_close (struct vty *);
char *vty_get_cwd (void);
void vty_log (const char *level, const char *proto, const char *fmt, va_list);
int vty_config_lock (struct vty *);
int vty_config_unlock (struct vty *);
int vty_shell (struct vty *);
int vty_shell_serv (struct vty *);
void vty_hello (struct vty *);
void *vty_current_index(struct vty *);
int vty_current_node(struct vty *vty);
enum node_type vty_go_parent(struct vty *vty);

extern void *tall_vty_ctx;

extern struct cmd_element cfg_description_cmd;
extern struct cmd_element cfg_no_description_cmd;


/**
 * signal handling
 */
enum signal_vty {
	S_VTY_EVENT,
};

struct vty_signal_data {
	enum event event;
	int sock;
	struct vty *vty;
};

/*! @} */