diff --git a/pandora_server/bin/pandora_db.pm b/pandora_server/bin/pandora_db.pm index 50b47a2ac3..1dfac2ecb8 100644 --- a/pandora_server/bin/pandora_db.pm +++ b/pandora_server/bin/pandora_db.pm @@ -600,76 +600,70 @@ sub module_generic_data_inc (%$$$$$) { if (ref($a_min) eq "HASH") { $a_min = ""; } - my $no_existe=0; - my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S"); - # Algoritmo: - # 1) Buscamos el valor anterior en la base de datos - # 2) Si el dato nuevo es mayor o igual, guardamos en la tabla de datos general la diferencia y en la tabla de estado de datos incrementales, modificamos el valor por el actual. - # 3) Si el dato nuevo es menor, guardamos el valor completo en la tabla de datos general y en la tabla de estado de datos incrementales, modificamos el valor por el actual. - - # Luego: - # a) Obtener valor anterior, si no existe, el valor anterior sera 0 - # b) Comparar ambos valores (anterior y actual) - # c) Actualizar tabla de estados de valores incrementales - # d) Insertar valor en tabla de valores de datos generales + # my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S"); + # Algorith description: + # 1) Search prev. value in database + # 2) If new value is bigger than previous, store in tagente_datos differente between + # last value and actual value, and in aux. table tagente_datos_inc the last real value + # 3) If new data is lower than previous or no previous value (RESET), store 0 in tagente_datos and store + # real value in aux. table, replacing the old one # Obtemos los ID's a traves del paquete de datos - my $id_agente = dame_agente_id($pa_config, $agent_name, $dbh); - my $id_modulo = dame_modulo_id($pa_config, $module_type, $dbh); # Fixed type here, its OK, dont change ! + my $id_agente = dame_agente_id ($pa_config, $agent_name, $dbh); + my $id_modulo = dame_modulo_id ($pa_config, $module_type, $dbh); my $id_agente_modulo = dame_agente_modulo_id($pa_config,$id_agente,$id_modulo,$m_name,$dbh); - my $query_idag = "select * from tagente_datos_inc where id_agente_modulo = $id_agente_modulo"; + # Take last real data from tagente_datos_inc # in this table, store the last real data, not the difference who its stored in tagente_datos table and # tagente_estado table - my $s_idag = $dbh->prepare($query_idag); - my $diferencia; my @data_row; my $data_anterior; - $s_idag ->execute; - if ($s_idag->rows == 0) { - $diferencia = 0; + + my $diferencia = 0; + my $no_existe = 0; + my $need_reset = 0; + my $need_update = 0; + my $new_data = 0; + my $data_anterior; + + if ($id_agente_modulo == -1) { $no_existe = 1; + $id_agente_modulo = crea_agente_modulo ($pa_config, $agent_name, $module_type, $m_name, $a_max, $a_min, $a_desc, $dbh); } else { - @data_row = $s_idag->fetchrow_array(); + my $query_idag = "SELECT * FROM tagente_datos_inc WHERE id_agente_modulo = $id_agente_modulo"; + my $s_idag = $dbh->prepare($query_idag); + $s_idag->execute; + my @data_row = $s_idag->fetchrow_array(); $data_anterior = $data_row[2]; $diferencia = $m_data - $data_anterior; - if ($diferencia < 0){ # New value is lower than old value, resetting inc system - my $query2 = "update tagente_datos_inc set datos = '$m_data' where id_agente_modulo = $id_agente_modulo"; - my $queryexec = $dbh->prepare($query2); - $queryexec->execute; - $queryexec->finish(); - $diferencia=0; + if ($diferencia < 0 ){ + $need_reset = 1; } + $s_idag -> finish(); } - $s_idag->finish(); - # c) Actualizar tabla de estados de valores incrementales (se pone siempre el ultimo valor) - - # tagente_datos_inc stores real data, not incremental data + + # Update of tagente_datos_inx (AUX TABLE) if ($no_existe == 1){ - my $query = "insert into tagente_datos_inc (id_agente_modulo,datos,timestamp) VALUES ($id_agente_modulo,'$m_data','$timestamp')"; + my $query = "INSERT INTO tagente_datos_inc (id_agente_modulo,datos) VALUES ($id_agente_modulo, '$m_data')"; $dbh->do($query); - } else { # If exists, modfy - if ($diferencia > 0) { - my $query_idag = "update tagente_datos_inc set datos = '$m_data' where id_agente_modulo = $id_agente_modulo"; - $s_idag = $dbh->prepare($query_idag); - $s_idag ->execute; - $s_idag->finish(); + } else { + # Data exists previously + if ($diferencia != 0) { + my $query2 = "UPDATE tagente_datos_inc SET datos = '$m_data' WHERE id_agente_modulo = $id_agente_modulo"; + $dbh->do($query2); } } - my $nuevo_data = 0; + if ($diferencia >= 0) { - if ($no_existe==0) { - $nuevo_data = $diferencia; - } - } else { # Si diferencia = 0 o menor (problemilla?) - if ($no_existe !=0){ - # Houston, we have a Problem ! - logger($pa_config, "ERROR: Error inside data_inc algorithm, for Agent $agent_name and Type Generic_data_inc ",6); - } + $new_data = $diferencia; + } + + # Update of tagente_datos and tagente_estado ? (only where there is a difference (or reset)) + if ($no_existe == 0){ + pandora_writedata ($pa_config, $m_timestamp, $agent_name, $module_type, $m_name, $new_data, $a_max, $a_min, $a_desc, $dbh, \$bUpdateDatos); + # Inc status is always 100 (N/A) + pandora_writestate ($pa_config, $agent_name, $module_type, $m_name, $new_data, 100, $dbh, $bUpdateDatos); } - pandora_writedata ($pa_config, $m_timestamp, $agent_name, $module_type, $m_name, $nuevo_data, $a_max, $a_min, $a_desc, $dbh, \$bUpdateDatos); - # Inc status is always 100 (N/A) - pandora_writestate ($pa_config, $agent_name, $module_type, $m_name, $nuevo_data, 100, $dbh, $bUpdateDatos); } else { - logger ($pa_config, "(data_inc) Invalid data received from $agent_name, module $m_name",2); + logger ($pa_config, "(data_inc) Invalid data received from $agent_name, module $m_name", 2); } } @@ -732,6 +726,12 @@ sub pandora_writedata (%$$$$$$$$$$){ my $Ref_bUpdateDatos = $_[10]; my @data; + if (!defined($max)){ + $max = "0"; + } + if (!defined($min)){ + $min = "0"; + } # Obtenemos los identificadores my $id_agente = dame_agente_id($pa_config, $nombre_agente,$dbh); # Check if exists module and agent_module reference in DB, if not, and learn mode activated, insert module in DB @@ -762,8 +762,7 @@ sub pandora_writedata (%$$$$$$$$$$){ if (dame_learnagente($pa_config, $id_agente,$dbh) eq "1"){ # Try to write a module and agent_module definition for that datablock logger( $pa_config, "Pandora_insertdata will create module (learnmode) for agent $nombre_agente",6); - crea_agente_modulo ($pa_config, $nombre_agente, $tipo_modulo, $nombre_modulo, $max, $min, $descripcion, $dbh); - $id_agente_modulo = dame_agente_modulo_id ($pa_config, $id_agente, $id_modulo, $nombre_modulo, $dbh); + $id_agente_modulo = crea_agente_modulo ($pa_config, $nombre_agente, $tipo_modulo, $nombre_modulo, $max, $min, $descripcion, $dbh); $needscreate = 1; # Really needs to be created } else { logger( $pa_config, "VERBOSE: pandora_insertdata cannot find module definition ($nombre_modulo / $tipo_modulo )for agent $nombre_agente - Use LEARN MODE for autocreate.",2); @@ -1063,23 +1062,25 @@ sub pandora_audit (%$$$$) { ########################################################################## sub dame_agente_id (%$$) { my $pa_config = $_[0]; - my $nombre_agente = sqlWrap($_[1]); + my $agent_name = $_[1]; my $dbh = $_[2]; - my $id_agente;my @data; - if (defined($nombre_agente)){ + if ( (defined($agent_name)) && ($agent_name ne "") ){ + my $id_agente; + my @data; + $agent_name = sqlWrap ($agent_name); # Calculate agent ID using select by its name - my $query_idag = "SELECT id_agente FROM tagente WHERE nombre = $nombre_agente"; + my $query_idag = "SELECT id_agente FROM tagente WHERE nombre = $agent_name"; my $s_idag = $dbh->prepare($query_idag); $s_idag ->execute; if ($s_idag->rows == 0) { - logger ($pa_config, "ERROR dame_agente_id(): Cannot find agent called $nombre_agente. Returning -1",1); + logger ($pa_config, "ERROR dame_agente_id(): Cannot find agent called $agent_name. Returning -1", 1); logger ($pa_config, "ERROR: SQL Query is $query_idag ",2); - $data[0]=-1; + $id_agente = -1; } else { @data = $s_idag->fetchrow_array(); + $id_agente = $data[0]; } - $id_agente = $data[0]; $s_idag->finish(); return $id_agente; } else { @@ -1214,6 +1215,31 @@ sub dame_agente_nombre (%$$) { return $nombre_agente; } +########################################################################## +## SUB give_group_disabled (pa_config, id_group, dbh) +## Return disabled field from tgrupo table given a id_grupo +########################################################################## +sub give_group_disabled (%$$) { + my $pa_config = $_[0]; + my $id_group = $_[1]; + my $dbh = $_[2]; + + my $disabled = 0; + my @data; + my $query_idag = "SELECT disabled FROM tgrupo WHERE id_grupo = '$id_group'"; + my $s_idag = $dbh->prepare($query_idag); + $s_idag ->execute; + if ($s_idag->rows == 0) { + logger($pa_config, "ERROR give_group_disabled(): Cannot find group id $id_group",2); + logger($pa_config, "ERROR: SQL Query is $query_idag ",10); + } else { + @data = $s_idag->fetchrow_array(); + $disabled = $data[0]; + } + $s_idag->finish(); + return $disabled; +} + ########################################################################## ## SUB dame_modulo_id (nombre_modulo) @@ -1241,7 +1267,6 @@ sub dame_modulo_id (%$$) { return $id_modulo; } - ########################################################################## ## SUB dame_agente_modulo_id (id_agente, id_tipomodulo, nombre) ## Return agente_modulo ID, from tabla tagente_modulo, given id_agente, id_tipomodulo and name @@ -1468,15 +1493,15 @@ sub dame_ultimo_contacto (%$$) { ########################################################################## ## SUB crea_agente_modulo(nombre_agente, nombre_tipo_modulo, nombre_modulo) -## create an entry in tagente_modulo +## create an entry in tagente_modulo, return id of created tagente_modulo ########################################################################## sub crea_agente_modulo (%$$$$$$$) { my $pa_config = $_[0]; my $nombre_agente = $_[1]; my $tipo_modulo = $_[2]; my $nombre_modulo = $_[3]; - my $max = sqlWrap($_[4]); - my $min = sqlWrap($_[5]); + my $max = $_[4]; + my $min = $_[5]; my $descripcion = $_[6]; my $dbh = $_[7]; @@ -1484,15 +1509,17 @@ sub crea_agente_modulo (%$$$$$$$) { my $agente_id = dame_agente_id ($pa_config, $nombre_agente, $dbh); if ((!defined($max)) || ($max eq "")){ - $max =0; + $max = 0; } if ((!defined($min)) || ($min eq "")){ - $min =0; + $min = 0; } if ((!defined($descripcion)) || ($descripcion eq "")){ - $descripcion="N/A"; + $descripcion = "N/A"; } $descripcion = sqlWrap ($descripcion. "(*)" ); + $max = sqlWrap ($max); + $min = sqlWrap ($min); $nombre_modulo = sqlWrap ($nombre_modulo); my $query = "INSERT INTO tagente_modulo (id_agente,id_tipo_modulo,nombre,max,min,descripcion) VALUES ($agente_id, $modulo_id, $nombre_modulo, $max, $min, $descripcion)"; @@ -1505,6 +1532,7 @@ sub crea_agente_modulo (%$$$$$$$) { } logger( $pa_config, "DEBUG: Query for autocreate : $query ", 8); $dbh->do($query); + return $dbh->{'mysql_insertid'}; } diff --git a/pandora_server/bin/pandora_network.pl b/pandora_server/bin/pandora_network.pl index 097a2be001..f7182bd840 100755 --- a/pandora_server/bin/pandora_network.pl +++ b/pandora_server/bin/pandora_network.pl @@ -136,15 +136,13 @@ sub pandora_network_subsystem { my $max; my $min; my $module_interval; my $nombre; my $tcp_port; my $tcp_rcv; my $tcp_send; my $snmp_oid; my $snmp_community; my $ip_target; my $id_module_group; - my $timestamp_old; # Stores timestamp from tagente_estado table + my $timestamp_old = 0; # Stores timestamp from tagente_estado table my $id_agente_estado; # ID from tagente_estado table my $estado_cambio; # store tagente_estado cambio field my $estado_estado; # Store tagente_estado estado field my $agent_name; # Agent name my $agent_interval; # Agent interval my $agent_disabled; # Contains disabled field of tagente - my $module_result; # Result of module exec. - my $module_data; # data for modulestado and dbInsert my $agent_osdata; # Agent os data my $server_id; # My server id my $flag; @@ -155,8 +153,7 @@ sub pandora_network_subsystem { my $exec_sql; my $exec_sql2; my $exec_sql3; my $buffer; my $running; - my $timestamp_old = 0; - + $server_id = dame_server_id($pa_config, $pa_config->{'servername'}."_Net", $dbh); while ( 1 ) { logger ($pa_config,"Loop in Network Module Subsystem",10); @@ -192,7 +189,7 @@ sub pandora_network_subsystem { $exec_sql2->finish(); } # First: Checkout for enabled agents owned by this server - $query_sql2 = "select * from tagente where ( disabled = 0 and id_server = $server_id ) ".$buffer; + $query_sql2 = "SELECT * FROM tagente WHERE ( disabled = 0 AND id_server = $server_id ) ". $buffer; $exec_sql2 = $dbh->prepare($query_sql2); $exec_sql2 ->execute; while (@sql_data2 = $exec_sql2->fetchrow_array()) { @@ -263,7 +260,8 @@ sub pandora_network_subsystem { $ip_target = $sql_data[13]; $id_module_group = $sql_data[14]; $flag = $sql_data[15]; - if ($module_interval == 0) { # If module interval not defined, get value for agent interval instead + if ($module_interval == 0) { + # If module interval not defined, get value for agent interval instead $module_interval = $agent_interval; } # Look for an entry in tagente_estado @@ -276,10 +274,11 @@ sub pandora_network_subsystem { $id_agente_estado = $sql_data3[0]; $estado_cambio = $sql_data3[4]; $estado_estado = $sql_data3[5]; - $running = $sql_data3[11]; + $running = $sql_data3[10]; } else { $id_agente_estado = -1; $estado_estado = -1; + $running = 0; } $exec_sql3->finish(); # if timestamp of tagente_modulo + module_interval <= timestamp actual, exec module @@ -288,8 +287,10 @@ sub pandora_network_subsystem { my $err; my $limit1_timestamp = $timestamp_old + $module_interval; my $limit2_timestamp = $timestamp_old + ($module_interval*2); - - if ( ($limit2_timestamp < $current_timestamp) || (($running == 0) && ( $limit1_timestamp < $current_timestamp)) || ($flag == 1) ) { # Exec module, we are out time limit ! + if ( ($limit2_timestamp < $current_timestamp) || + (($running == 0) && ( $limit1_timestamp < $current_timestamp)) || + ($flag == 1) ) + { # Exec module, we are out time limit ! if ($flag == 1){ # Reset flag to 0 $query_sql3 = "UPDATE tagente_modulo SET flag=0 WHERE id_agente_modulo = $id_agente_modulo"; $exec_sql3 = $dbh->prepare($query_sql3); @@ -302,7 +303,7 @@ sub pandora_network_subsystem { $exec_sql3 ->execute; $exec_sql3->finish(); logger ($pa_config, "Network Module Subsystem ($nettypedesc): Exec Netmodule '$nombre' ID $id_agente_modulo ",4); - exec_network_module( $id_agente, $id_agente_estado, $id_tipo_modulo, $nombre, $min, $max, $agent_interval, $tcp_port, $tcp_send, $tcp_rcv, $snmp_community, $snmp_oid, $ip_target, $module_result, $module_data, $estado_cambio, $estado_estado, $agent_name, $agent_osdata, $id_agente_modulo, $pa_config, $dbh); + exec_network_module( $id_agente, $id_agente_estado, $id_tipo_modulo, $nombre, $min, $max, $agent_interval, $tcp_port, $tcp_send, $tcp_rcv, $snmp_community, $snmp_oid, $ip_target, $estado_cambio, $estado_estado, $agent_name, $agent_osdata, $id_agente_modulo, $pa_config, $dbh); } # Timelimit if } # while $exec_sql->finish(); @@ -337,7 +338,7 @@ sub pandora_ping_icmp { # tcp_rcv, id_tipo_module, dbh) # Makes a call to TCP modules to get a value. ########################################################################## -sub pandora_query_tcp { +sub pandora_query_tcp (%$$$$$$$$) { my $pa_config = $_[0]; my $tcp_port = $_[1]; my $ip_target = $_[2]; @@ -350,7 +351,7 @@ sub pandora_query_tcp { my $temp; my $temp2; my $tam; - + my $handle=IO::Socket::INET->new( Proto=>"tcp", PeerAddr=>$ip_target, @@ -366,7 +367,7 @@ sub pandora_query_tcp { # Replace Carriage rerturn and line feed $handle->send($tcp_send); } - # we expect to receive data ? + # we expect to receive data ? (non proc types) if (($tcp_rcv ne "") || ($id_tipo_modulo == 10) || ($id_tipo_modulo ==8) || ($id_tipo_modulo == 11)) { # Receive data, non-blocking !!!! (VERY IMPORTANT!) $temp2 = ""; @@ -380,39 +381,41 @@ sub pandora_query_tcp { } if ($id_tipo_modulo == 9){ # only for TCP Proc if ($temp2 =~ /$tcp_rcv/i){ # String match ! - $module_data = 1; - $module_result = 0; + $$module_data = 1; + $$module_result = 0; } else { - $module_data = 0; - $module_result = 0; + $$module_data = 0; + $$module_result = 0; } } elsif ($id_tipo_modulo == 10 ){ # TCP String (no int conversion)! - $module_data = $temp2; - $module_result =0; + $$module_data = $temp2; + $$module_result =0; } else { # TCP Data numeric (inc or data) if ($temp2 ne ""){ if ($temp2 =~ /[A-Za-z\.\,\-\/\\\(\)\[\]]/){ - $module_result=1; # init - $module_data = 0; # invalid data + $$module_result = 1; + $$module_data = 0; # invalid data } else { - $module_data = int($temp2); - $module_result = 0; # Successful + $$module_data = int($temp2); + $$module_result = 0; # Successful + } + } else { + $$module_result = 1; + $$module_data = 0; # invalid data } - } - $module_result = 0; # Successful } } else { # No expected data to receive, if connected and tcp_proc type successful if ($id_tipo_modulo == 9){ # TCP Proc - $module_result = 0; - $module_data = 1; + $$module_result = 0; + $$module_data = 1; } } $handle->close(); } else { # Cannot connect (open sock failed) - $module_result = 1; # Fail + $$module_result = 1; # Fail if ($id_tipo_modulo == 9){ # TCP Proc - $module_result = 0; - $module_data = 0; # Failed, but data exists + $$module_result = 0; + $$module_data = 0; # Failed, but data exists } } } @@ -484,20 +487,20 @@ sub exec_network_module { my $mysnmp_community = $_[10]; my $mysnmp_oid = $_[11]; my $ip_target = $_[12]; - my $module_result = $_[13]; - my $module_data = $_[14]; - my $estado_cambio = $_[15]; - my $estado_estado = $_[16]; - my $agent_name = $_[17]; - my $agent_osdata = $_[18]; - my $id_agente_modulo = $_[19]; - my $pa_config = $_[20]; - my $dbh = $_[21]; + my $estado_cambio = $_[13]; + my $estado_estado = $_[14]; + my $agent_name = $_[15]; + my $agent_osdata = $_[16]; + my $id_agente_modulo = $_[17]; + my $pa_config = $_[18]; + my $dbh = $_[19]; + my $error = "1"; my $query_sql2; my $temp=0; my $tam; my $temp2; - $module_result = 1; # Fail by default + my $module_result = 1; # Fail by default + my $module_data = 0; # ICMP Modules # ------------ @@ -561,11 +564,12 @@ sub exec_network_module { # ---------- } elsif (($id_tipo_modulo == 8) || ($id_tipo_modulo == 9) || ($id_tipo_modulo == 10) || ($id_tipo_modulo == 11)) { # TCP Module if (($tcp_port < 65536) && ($tcp_port > 0)){ # Port check - pandora_query_tcp ($pa_config, $tcp_port, $ip_target, \$module_result, \$module_data, $tcp_send, $tcp_rcv, $id_tipo_modulo, $dbh) + pandora_query_tcp ($pa_config, $tcp_port, $ip_target, \$module_result, \$module_data, $tcp_send, $tcp_rcv, $id_tipo_modulo, $dbh); } else { $module_result = 1; } } + # -------------------------------------------------------- # -------------------------------------------------------- if ($module_result == 0) { @@ -576,18 +580,18 @@ sub exec_network_module { $part{'max'}[0]=$max; $part{'min'}[0]=$min; my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S"); - my $tipo_modulo = dame_nombretipomodulo_idagentemodulo($pa_config, $id_tipo_modulo,$dbh); + my $tipo_modulo = dame_nombretipomodulo_idagentemodulo ($pa_config, $id_tipo_modulo, $dbh); if (($tipo_modulo eq 'remote_snmp') || ($tipo_modulo eq 'remote_icmp') || ($tipo_modulo eq 'remote_tcp') || ($tipo_modulo eq 'remote_udp')) { - module_generic_data($pa_config, \%part,$timestamp,$agent_name,$tipo_modulo,$dbh); + module_generic_data ($pa_config, \%part, $timestamp, $agent_name, $tipo_modulo, $dbh); } elsif ($tipo_modulo =~ /\_inc/ ) { - module_generic_data_inc($pa_config, \%part,$timestamp,$agent_name,$tipo_modulo,$dbh); + module_generic_data_inc ($pa_config, \%part, $timestamp, $agent_name, $tipo_modulo, $dbh); } elsif ($tipo_modulo =~ /\_string/) { - module_generic_data_string($pa_config, \%part,$timestamp,$agent_name,$tipo_modulo,$dbh); + module_generic_data_string ($pa_config, \%part, $timestamp, $agent_name, $tipo_modulo, $dbh); } elsif ($tipo_modulo =~ /\_proc/){ - module_generic_proc($pa_config, \%part,$timestamp,$agent_name,$tipo_modulo,$dbh); + module_generic_proc ($pa_config, \%part, $timestamp, $agent_name, $tipo_modulo, $dbh); } else { logger ($pa_config, "Problem with unknown module type '$tipo_modulo'", 0); @@ -596,8 +600,10 @@ sub exec_network_module { # Update agent last contact # Insert Pandora version as agent version pandora_lastagentcontact ($pa_config, $timestamp, $agent_name, $agent_osdata, $pa_config->{'version'}, $agent_interval, $dbh); - } else { # $module_result != 0) + } else { + # $module_result != 0) # Modules who cannot connect or something go bad, update last_try field + logger ($pa_config, "Cannot obtain exec Network Module $nombre from agent $agent_name", 4); my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S"); my $utimestamp = &UnixDate("today","%s"); my $query_act = "UPDATE tagente_estado SET utimestamp = $utimestamp, timestamp = '$timestamp', last_try = '$timestamp' WHERE id_agente_estado = $id_agente_estado "; diff --git a/pandora_server/bin/pandora_tools.pm b/pandora_server/bin/pandora_tools.pm index 887ccfd6f7..46aa8b3ce0 100644 --- a/pandora_server/bin/pandora_tools.pm +++ b/pandora_server/bin/pandora_tools.pm @@ -164,10 +164,12 @@ sub limpia_cadena { ######################################################################################## sub sqlWrap { - my $toBeWrapped = shift(@_); - $toBeWrapped =~ s/\'/\\\'/g; - $toBeWrapped =~ s/\"/\\\'/g; - return "'".$toBeWrapped."'"; + my $toBeWrapped = shift(@_); + if (defined $toBeWrapped){ + $toBeWrapped =~ s/\'/\\\'/g; + $toBeWrapped =~ s/\"/\\\'/g; + return "'".$toBeWrapped."'"; + } } ##########################################################################