vtysh: Add vty_socket cli option to override the compiled-in location for the VTY daemon sockets

Signed-off-by: Martin Winter <mwinter@opensourcerouting.org>
This commit is contained in:
Martin Winter 2017-01-26 00:43:58 +07:00
parent 7fa382d1d0
commit 87d79a9f79
3 changed files with 52 additions and 11 deletions

View File

@ -2898,13 +2898,34 @@ vtysh_connect (struct vtysh_client *vclient)
int sock, len; int sock, len;
struct sockaddr_un addr; struct sockaddr_un addr;
struct stat s_stat; struct stat s_stat;
char path[MAXPATHLEN];
if (vty_sock_path == NULL)
strlcpy (path, vclient->path, sizeof (path));
else {
/* Different path for VTY Socket specified
overriding the default path, but keep the filename */
strlcpy (path, vty_sock_path, sizeof (path));
if (strrchr (vclient->path, '/') != NULL)
strlcat (path, strrchr (vclient->path, '/'), sizeof (path));
else {
/*
* vclient->path configured as relative path during config? Should
* really never happen for sensible config
*/
strlcat (path, "/", sizeof (path));
strlcat (path, vclient->path, sizeof (path));
}
}
path[sizeof(path)-1] = '\0';
/* Stat socket to see if we have permission to access it. */ /* Stat socket to see if we have permission to access it. */
ret = stat (vclient->path, &s_stat); ret = stat (path, &s_stat);
if (ret < 0 && errno != ENOENT) if (ret < 0 && errno != ENOENT)
{ {
fprintf (stderr, "vtysh_connect(%s): stat = %s\n", fprintf (stderr, "vtysh_connect(%s): stat = %s\n",
vclient->path, safe_strerror(errno)); path, safe_strerror(errno));
exit(1); exit(1);
} }
@ -2913,7 +2934,7 @@ vtysh_connect (struct vtysh_client *vclient)
if (! S_ISSOCK(s_stat.st_mode)) if (! S_ISSOCK(s_stat.st_mode))
{ {
fprintf (stderr, "vtysh_connect(%s): Not a socket\n", fprintf (stderr, "vtysh_connect(%s): Not a socket\n",
vclient->path); path);
exit (1); exit (1);
} }
@ -2923,7 +2944,7 @@ vtysh_connect (struct vtysh_client *vclient)
if (sock < 0) if (sock < 0)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "vtysh_connect(%s): socket = %s\n", vclient->path, fprintf(stderr, "vtysh_connect(%s): socket = %s\n", path,
safe_strerror(errno)); safe_strerror(errno));
#endif /* DEBUG */ #endif /* DEBUG */
return -1; return -1;
@ -2931,7 +2952,7 @@ vtysh_connect (struct vtysh_client *vclient)
memset (&addr, 0, sizeof (struct sockaddr_un)); memset (&addr, 0, sizeof (struct sockaddr_un));
addr.sun_family = AF_UNIX; addr.sun_family = AF_UNIX;
strncpy (addr.sun_path, vclient->path, strlen (vclient->path)); strncpy (addr.sun_path, path, strlen (path));
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
len = addr.sun_len = SUN_LEN(&addr); len = addr.sun_len = SUN_LEN(&addr);
#else #else
@ -2942,7 +2963,7 @@ vtysh_connect (struct vtysh_client *vclient)
if (ret < 0) if (ret < 0)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "vtysh_connect(%s): connect = %s\n", vclient->path, fprintf(stderr, "vtysh_connect(%s): connect = %s\n", path,
safe_strerror(errno)); safe_strerror(errno));
#endif /* DEBUG */ #endif /* DEBUG */
close (sock); close (sock);
@ -2993,14 +3014,23 @@ vtysh_update_all_insances(struct vtysh_client * head_client)
{ {
struct vtysh_client *client; struct vtysh_client *client;
char *ptr; char *ptr;
char vty_dir[MAXPATHLEN];
DIR *dir; DIR *dir;
struct dirent *file; struct dirent *file;
int n = 0; int n = 0;
if (head_client->flag != VTYSH_OSPFD) return; if (head_client->flag != VTYSH_OSPFD) return;
if (vty_sock_path == NULL)
/* ls DAEMON_VTY_DIR and look for all files ending in .vty */ /* ls DAEMON_VTY_DIR and look for all files ending in .vty */
dir = opendir(DAEMON_VTY_DIR "/"); strlcpy(vty_dir, DAEMON_VTY_DIR "/", MAXPATHLEN);
else
{
/* ls vty_sock_dir and look for all files ending in .vty */
strlcpy(vty_dir, vty_sock_path, MAXPATHLEN);
strlcat(vty_dir, "/", MAXPATHLEN);
}
dir = opendir(vty_dir);
if (dir) if (dir)
{ {
while ((file = readdir(dir)) != NULL) while ((file = readdir(dir)) != NULL)
@ -3010,8 +3040,8 @@ vtysh_update_all_insances(struct vtysh_client * head_client)
if (n == MAXIMUM_INSTANCES) if (n == MAXIMUM_INSTANCES)
{ {
fprintf(stderr, fprintf(stderr,
"Parsing %s/, client limit(%d) reached!\n", "Parsing %s, client limit(%d) reached!\n",
DAEMON_VTY_DIR, n); vty_dir, n);
break; break;
} }
client = (struct vtysh_client *) malloc(sizeof(struct vtysh_client)); client = (struct vtysh_client *) malloc(sizeof(struct vtysh_client));
@ -3019,7 +3049,7 @@ vtysh_update_all_insances(struct vtysh_client * head_client)
client->name = "ospfd"; client->name = "ospfd";
client->flag = VTYSH_OSPFD; client->flag = VTYSH_OSPFD;
ptr = (char *) malloc(100); ptr = (char *) malloc(100);
sprintf(ptr, "%s/%s", DAEMON_VTY_DIR, file->d_name); sprintf(ptr, "%s%s", vty_dir, file->d_name);
client->path = (const char *)ptr; client->path = (const char *)ptr;
client->next = NULL; client->next = NULL;
vtysh_client_sorted_insert(head_client, client); vtysh_client_sorted_insert(head_client, client);

View File

@ -96,4 +96,6 @@ extern int execute_flag;
extern struct vty *vty; extern struct vty *vty;
extern char * vty_sock_path;
#endif /* VTYSH_H */ #endif /* VTYSH_H */

View File

@ -53,6 +53,9 @@ char history_file[MAXPATHLEN];
/* Flag for indicate executing child command. */ /* Flag for indicate executing child command. */
int execute_flag = 0; int execute_flag = 0;
/* VTY Socket prefix */
char * vty_sock_path = NULL;
/* For sigsetjmp() & siglongjmp(). */ /* For sigsetjmp() & siglongjmp(). */
static sigjmp_buf jmpbuf; static sigjmp_buf jmpbuf;
@ -144,6 +147,7 @@ usage (int status)
"-f, --inputfile Execute commands from specific file and exit\n" \ "-f, --inputfile Execute commands from specific file and exit\n" \
"-E, --echo Echo prompt and command in -c mode\n" \ "-E, --echo Echo prompt and command in -c mode\n" \
"-C, --dryrun Check configuration for validity and exit\n" \ "-C, --dryrun Check configuration for validity and exit\n" \
" --vty_socket Override vty socket path\n" \
"-m, --markfile Mark input file with context end\n" "-m, --markfile Mark input file with context end\n"
"-w, --writeconfig Write integrated config (Quagga.conf) and exit\n" "-w, --writeconfig Write integrated config (Quagga.conf) and exit\n"
"-h, --help Display this help and exit\n\n" \ "-h, --help Display this help and exit\n\n" \
@ -156,6 +160,7 @@ usage (int status)
} }
/* VTY shell options, we use GNU getopt library. */ /* VTY shell options, we use GNU getopt library. */
#define OPTION_VTYSOCK 1000
struct option longopts[] = struct option longopts[] =
{ {
{ "boot", no_argument, NULL, 'b'}, { "boot", no_argument, NULL, 'b'},
@ -163,6 +168,7 @@ struct option longopts[] =
{ "eval", required_argument, NULL, 'e'}, { "eval", required_argument, NULL, 'e'},
{ "command", required_argument, NULL, 'c'}, { "command", required_argument, NULL, 'c'},
{ "daemon", required_argument, NULL, 'd'}, { "daemon", required_argument, NULL, 'd'},
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{ "inputfile", required_argument, NULL, 'f'}, { "inputfile", required_argument, NULL, 'f'},
{ "echo", no_argument, NULL, 'E'}, { "echo", no_argument, NULL, 'E'},
{ "dryrun", no_argument, NULL, 'C'}, { "dryrun", no_argument, NULL, 'C'},
@ -310,6 +316,9 @@ main (int argc, char **argv, char **env)
tail = cr; tail = cr;
} }
break; break;
case OPTION_VTYSOCK:
vty_sock_path = optarg;
break;
case 'd': case 'd':
daemon_name = optarg; daemon_name = optarg;
break; break;