aboutsummaryrefslogtreecommitdiffstats
path: root/web/api/write/switch-add
blob: 3950b105e11ce644f6f91db8f8f37aef0dafbb5b (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
#! /usr/bin/perl
# vim:ts=8:sw=8

#use CGI qw(fatalsToBrowser);
use DBI;
use lib '/opt/nms/include';
use nms;
use nms::web qw(%get_params %json finalize_output get_input $dbh);
use nms::util qw(guess_placement);
use strict;
use warnings;
use JSON;
use Data::Dumper;

$nms::web::cc{'max-age'} = "0";

my $in = get_input();
my @tmp = @{JSON::XS::decode_json($in)};

my @added;
my @dups;

my $sth = $nms::web::dbh->prepare("SELECT sysname FROM switches WHERE sysname=?");

my @fields = ( 'community', 'current_mac', 'distro_name', 'distro_phy_port', 'lldp_chassis_id', 'mgmt_v4_addr', 'mgmt_v4_gw', 'mgmt_v6_addr', 'mgmt_v6_gw', 'mgmt_vlan', 'placement', 'poll_frequency', 'subnet4', 'subnet6', 'switchtype', 'sysname', 'traffic_vlan');

sub convertplace
{
	my %in = %{$_[0]};
	my %out = ();

	if (not defined $in{'x1'} and defined($in{'x'})) {
		$out{'x1'} = int($in{'x'});
		$out{'y1'} = int($in{'y'});
		$out{'xx'} = int($in{'x'} + $in{'width'});
		$out{'yy'} = int($in{'y'} + $in{'height'});
	} else {
		return \%in;
	}
	return \%out;
}

foreach my $tmp2 (@tmp) {
	my %switch = %{$tmp2};
	my $affected = 0;
	my %template = ();
	map { $template{$_} = 'DEFAULT' } @fields;
	if (not defined($switch{'sysname'})) {
		next;
	}

	$sth->execute( $switch{'sysname'});
	while ( my @row = $sth->fetchrow_array ) {
		$affected += 1;
	}

	if ($affected == 0) {
		my %placement;
		if (not defined ($switch{'placement'})) {
			%placement = guess_placement($switch{'sysname'});
		} else {
			%placement = %{convertplace($switch{'placement'})};
		}
		if (not defined($switch{'ip'}) and defined($switch{'mgtmt4'})) {
			$switch{'ip'} = $switch{'mgtmt4'};
		}
		if (not defined($switch{'secondary_ip'}) and defined($switch{'mgtmt6'})) {
			$switch{'secondary_ip'} = $switch{'mgtmt6'};
		}
		my ($x1,$x2,$y1,$y2);
		$x1 = $placement{'x1'};
		$y1 = $placement{'y1'};
		$x2 = $placement{'xx'};
		$y2 = $placement{'yy'};
		$switch{'placement'} = "(($x1,$y1),($x2,$y2))";
		
		map {
			if (defined ($template{$_})) {
					$template{$_} = $dbh->quote($switch{$_});
			}
		} keys %switch;
		

		$nms::web::dbh->do("INSERT INTO SWITCHES (mgmt_v4_addr, sysname, poll_frequency, community, lldp_chassis_id, mgmt_v6_addr, placement,subnet4,subnet6,distro_name)  VALUES ($template{'mgmt_v4_addr'}, $template{'sysname'}, $template{'poll_frequency'}, $template{'community'}, $template{'lldp_chassis_id'}, $template{'mgmt_v6_addr'}, $template{'placement'},$template{'subnet4'},$template{'subnet6'},$template{'distro_name'});");
		push @added, $switch{'sysname'};
	}
}

$json{'switches_addded'} = \@added;

print "X-ban: /api/.*switches.*\n";
finalize_output();
>->iface_in, global.conf->port, &hints, &addrinfo_bind); if (i) { log_message(LOGLVL_ERROR, "Couldn't parse address `%s': %s", global.conf->iface_in, gai_strerror(i)); return -1; } global.listen_socket = -1; /* Try IPv6 first (which will become an IPv6+IPv4 socket). */ for (res = addrinfo_bind; res; res = res->ai_next) { if (res->ai_family == AF_INET6 && try_listen(res)) { break; } } /* The rest (so IPv4, I guess). */ if (res == NULL) { for (res = addrinfo_bind; res; res = res->ai_next) { if (res->ai_family != AF_INET6 && try_listen(res)) { break; } } } freeaddrinfo(addrinfo_bind); i = listen(global.listen_socket, 10); if (i == -1) { log_error("listen"); return(-1); } global.listen_watch_source_id = b_input_add(global.listen_socket, B_EV_IO_READ, bitlbee_io_new_client, NULL); if (!global.conf->nofork) { i = fork(); if (i == -1) { log_error("fork"); return(-1); } else if (i != 0) { exit(0); } setsid(); i = chdir("/"); /* Don't use i, just make gcc happy. :-/ */ if (getenv("_BITLBEE_RESTART_STATE") == NULL) { for (i = 0; i < 3; i++) { if (close(i) == 0) { /* Keep something bogus on those fd's just in case. */ open("/dev/null", O_WRONLY); } } } } if (global.conf->runmode == RUNMODE_FORKDAEMON) { ipc_master_load_state(getenv("_BITLBEE_RESTART_STATE")); } if (global.conf->runmode == RUNMODE_DAEMON || global.conf->runmode == RUNMODE_FORKDAEMON) { ipc_master_listen_socket(); } if ((fp = fopen(global.conf->pidfile, "w"))) { fprintf(fp, "%d\n", (int) getpid()); fclose(fp); } else { log_message(LOGLVL_WARNING, "Warning: Couldn't write PID to `%s'", global.conf->pidfile); } if (!global.conf->nofork) { log_link(LOGLVL_ERROR, LOGOUTPUT_SYSLOG); log_link(LOGLVL_WARNING, LOGOUTPUT_SYSLOG); } return(0); } int bitlbee_inetd_init() { if (!irc_new(0)) { return(1); } return(0); } gboolean bitlbee_io_current_client_read(gpointer data, gint fd, b_input_condition cond) { irc_t *irc = data; char line[513]; int st; st = read(irc->fd, line, sizeof(line) - 1); if (st == 0) { irc_abort(irc, 1, "Connection reset by peer"); return FALSE; } else if (st < 0) { if (sockerr_again()) { return TRUE; } else { irc_abort(irc, 1, "Read error: %s", strerror(errno)); return FALSE; } } line[st] = '\0'; if (irc->readbuffer == NULL) { irc->readbuffer = g_strdup(line); } else { irc->readbuffer = g_renew(char, irc->readbuffer, strlen(irc->readbuffer) + strlen(line) + 1); strcpy((irc->readbuffer + strlen(irc->readbuffer)), line); } irc_process(irc); /* Normally, irc_process() shouldn't call irc_free() but irc_abort(). Just in case: */ if (!g_slist_find(irc_connection_list, irc)) { log_message(LOGLVL_WARNING, "Abnormal termination of connection with fd %d.", fd); return FALSE; } /* Very naughty, go read the RFCs! >:) */ if (irc->readbuffer && (strlen(irc->readbuffer) > 1024)) { irc_abort(irc, 0, "Maximum line length exceeded"); return FALSE; } return TRUE; } gboolean bitlbee_io_current_client_write(gpointer data, gint fd, b_input_condition cond) { irc_t *irc = data; int st, size; char *temp; if (irc->sendbuffer == NULL) { return FALSE; } size = strlen(irc->sendbuffer); st = write(irc->fd, irc->sendbuffer, size); if (st == 0 || (st < 0 && !sockerr_again())) { irc_abort(irc, 1, "Write error: %s", strerror(errno)); return FALSE; } else if (st < 0) { /* && sockerr_again() */ return TRUE; } if (st == size) { g_free(irc->sendbuffer); irc->sendbuffer = NULL; irc->w_watch_source_id = 0; return FALSE; } else { temp = g_strdup(irc->sendbuffer + st); g_free(irc->sendbuffer); irc->sendbuffer = temp; return TRUE; } } static gboolean bitlbee_io_new_client(gpointer data, gint fd, b_input_condition condition) { socklen_t size = sizeof(struct sockaddr_in); struct sockaddr_in conn_info; int new_socket = accept(global.listen_socket, (struct sockaddr *) &conn_info, &size); if (new_socket == -1) { log_message(LOGLVL_WARNING, "Could not accept new connection: %s", strerror(errno)); return TRUE; } if (global.conf->runmode == RUNMODE_FORKDAEMON) { pid_t client_pid = 0; int fds[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) { log_message(LOGLVL_WARNING, "Could not create IPC socket for client: %s", strerror(errno)); fds[0] = fds[1] = -1; } sock_make_nonblocking(fds[0]); sock_make_nonblocking(fds[1]); client_pid = fork(); if (client_pid > 0 && fds[0] != -1) { struct bitlbee_child *child; /* TODO: Stuff like this belongs in ipc.c. */ child = g_new0(struct bitlbee_child, 1); child->pid = client_pid; child->ipc_fd = fds[0]; child->ipc_inpa = b_input_add(child->ipc_fd, B_EV_IO_READ, ipc_master_read, child); child->to_fd = -1; child_list = g_slist_append(child_list, child); log_message(LOGLVL_INFO, "Creating new subprocess with pid %d.", (int) client_pid); /* Close some things we don't need in the parent process. */ close(new_socket); close(fds[1]); } else if (client_pid == 0) { irc_t *irc; b_main_init(); /* Close the listening socket, we're a client. */ close(global.listen_socket); b_event_remove(global.listen_watch_source_id); /* Make the connection. */ irc = irc_new(new_socket); /* We can store the IPC fd there now. */ global.listen_socket = fds[1]; global.listen_watch_source_id = b_input_add(fds[1], B_EV_IO_READ, ipc_child_read, irc); close(fds[0]); ipc_master_free_all(); } } else { log_message(LOGLVL_INFO, "Creating new connection with fd %d.", new_socket); irc_new(new_socket); } return TRUE; } gboolean bitlbee_shutdown(gpointer data, gint fd, b_input_condition cond) { /* Send the message here with now=TRUE to ensure it arrives */ irc_write_all(TRUE, "ERROR :Closing link: BitlBee server shutting down"); /* Try to save data for all active connections (if desired). */ while (irc_connection_list != NULL) { irc_abort(irc_connection_list->data, TRUE, NULL); } /* We'll only reach this point when not running in inetd mode: */ b_main_quit(); return FALSE; }