Sponsors

Google
- Epoch Time
A quick idea by Chris Rowe follow me @chrisrowe  •  Help spread the word and tweet about this site  •  What's the Epoch

Size of MySQL database

Vogliamo sapere lo spazio occupato da ogni singolo database usando la command line, una semplice query restituisce a video l'informazione richiesta. Prestate attenzione perché questa query potrebbe richiedere molto tempo per DB di grandi dimensioni.


mysql> SELECT table_schema "DB Name",
Round(Sum(data_length + index_length) / 1024 / 1024, 1) "DB Size in MB"
FROM information_schema.tables
GROUP BY table_schema;


Ecco un esempio dell'output:

+--------------------------------+---------------+
| DB Name | DB Size in MB |
+--------------------------------+---------------+
| monitoraggio | 1505.0 |
| mysql | 0.7 |
| pcparts | 0.4 |
| performance_schema | 0.0 |
| photogulp | 193.3 |
| photogulp_webalbum | 0.5 |
| phplistdb | 33.4 |
| pixellone_artistika | 7.9 |
| pixellone_enter | 0.4 |
| rc-bazar_oc | 4.8 |
| wordpress_9 | 1.1 |
+--------------------------------+---------------+

Test IMAP command line

Dobbiamo testare che il mailserver funzioni correttamente senza configurare il client di post, possiamo farlo usando il telnet.
In blu i comandi da lanciare e in girigio la risposta del server:


[domenico@lbit-solution ~]$ telnet server.com imap
Trying 185.7.40.62...
Connected to serever.com.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS AUTH=PLAIN AUTH=LOGIN] Dovecot ready.
a1 LOGIN utente password
a1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS] Logged in
a2 LIST "" "*"
* LIST (\HasNoChildren) "." "Trash"
* LIST (\HasNoChildren) "." "Posta inviata"
* LIST (\HasNoChildren) "." "Sent"
* LIST (\HasNoChildren) "." "Posta indesiderata"
* LIST (\HasNoChildren) "." "Drafts"
* LIST (\HasNoChildren) "." "Posta eliminata"
* LIST (\HasNoChildren) "." "INBOX"
a2 OK List completed.
a3 EXAMINE INBOX
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $MDNSent)
* OK [PERMANENTFLAGS ()] Read-only mailbox.
* 8 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 1404316555] UIDs valid
* OK [UIDNEXT 20] Predicted next UID
* OK [HIGHESTMODSEQ 1] Highest
a3 OK [READ-ONLY] Select completed..
a4 FETCH 1 BODY[]
* 1 FETCH (BODY[] {447}
Return-Path:
X-Original-To: sk
Delivered-To: utente@server.com
Received: from localhost (localhost [127.0.0.1])
        by web.server.com (Postfix) with ESMTP id DB08D7F48B
        for ; Wed,  2 Jul 2014 17:52:17 +0200 (CEST)
Message-Id: <20140702155221 .db08d7f48b="" web.server.com="">
Date: Wed,  2 Jul 2014 17:52:17 +0200 (CEST)
From: utente@server.com
To: undisclosed-recipients:;

welcome to unixmen mail server
)
a4 OK Fetch completed.
a5 LOGOUT
* BYE Logging out
a5 OK Logout completed.
Connection closed by foreign host.
[domenico@lbit-solution ~]$




MySQL UDF Perl Regular Expression


Leggi l'articolo sul BLOG LBiT:
http://blog.lbit-solution.it/2013/11/mysql-udf-perl-regular-expression/

Nel realizzare nuovi scraper per g4play.it Emanuele si è reso conto che la nostra istanza MySQL  non supporta le espressioni regolari, a lui non servono solo query di ricerca ma manipolazioni di dati complesse. Con estrema semplicità mi chiede di installare la libreria lib_mysqludf_preg, non è complicato, ma neanche così banale. Iniziamo subito con l'installazione dei pacchetti che ci serviranno:

  [root@mysqllbit lib_mysqludf_preg]# yum install pcre pcre-devel [root@mysqllbit lib_mysqludf_preg]# yum install make gcc gcc-c++ [root@mysqllbit lib_mysqludf_preg]# yum install mysql-devel

 Questo per evitare tutti gli errori relativi al compilatore, a pcre e mysql. Scarichiamo il paccheto da GitHub:

[root@mysqllbit lib_mysqludf_preg]# wget https://github.com/mysqludf/lib_mysqludf_preg/archive/testing.zip
[root@mysqllbit lib_mysqludf_preg]# unzip testing.zip

  ora lanciamo il configuratore

[root@mysqllbit lib_mysqludf_preg]# ./configure

  ci siamo risparmiati gli errori avendo installato preventivamente i pacchetti, l'unico messaggio a video con la parola ERROR è

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
  Possiamo rilassarci, avendo settato la password di root è normale che non riesca ad accedere. Ora installiamo:

[root@mysqllbit lib_mysqludf_preg]# make
[root@mysqllbit lib_mysqludf_preg]# make install
[root@mysqllbit lib_mysqludf_preg]# make installdb

ERROR 1548 (HY000) at line 5: Cannot load from mysql.proc. The table is probably corrupted
make: *** [uninstalldb] Error 1

  Sull'ultimo passaggio ho ricevuto errore di tabella corrotta, per questo ho dovuto prima "sistemare" le tabelle MySQL e poi rilanciare il make installdb

[root@mysqllbit lib_mysqludf_preg]# make installdb
/usr/bin/mysql -p <./uninstalldb.sql 
Enter password: 
cat installdb.sql | sed 's/\.so/.dll/g' >installdb_win.sql
if test -f .libs/lib_mysqludf_preg.dll; then  \
                /usr/bin/mysql -p <./installdb_win.sql; \
        else \
                /usr/bin/mysql -p <./installdb.sql;\
        fi
Enter password:
[root@mysqllbit lib_mysqludf_preg]# make test
cd test; make test
make[1]: Entering directory `/usr/local/lib/lib_mysqludf_preg/test'
/usr/bin/mysqltest -p --include=create_testdb.sql  --result-f...
Enter password:
ok
/usr/bin/mysqltest -p --include=create_testdb.sql  --result-f...
Enter password:
ok
/usr/bin/mysqltest -p --include=create_testdb.sql  --result-f...
Enter password:
ok
/usr/bin/mysqltest -p --include=create_testdb.sql  --result-fi...
Enter password:
ok
/usr/bin/mysqltest -p --include=create_testdb.sql  --result-f...
Enter password:
ok
/usr/bin/mysqltest -p --include=create_testdb.sql  --result-f...
Enter password:
ok
make[1]: Leaving directory `/usr/local/lib/lib_mysqludf_preg/test'

Finito, ora Emanuele potrà usare le espressioni regolari per manipolare i dati di g4play.it.

Monitoraggio Web Server con mail e sms alerting

Esigenza: monitorare il servizio erogato da alcuni server e ricevere allarmi via MAIL e SMS in caso di degrado o fermo servizio

 

Leggi l'artiolo sul BLOG LBiT 

 

Lo script qui sotto potrebbe sembrare molto complesso ma realmente sono pochissimi comandi della bash che, in base al risultato ottenuto, producono dei file, uno è l'html per la mail, l'altro è un file PHP per l'invio si SMS utilizando Subito SMS come gateway SMS. Il servizio da monitorare è Apachi e Mysql, utilizzeremo bash e PHP per fare questo. Per prima cosa creiamo un file php da mettere su ogni server che vogliamo moitorare, noi abbiamo inserito una semplice connessione al DB:

<?php
$link = mysql_connect('127.0.0.1','username','password');
   if (!$link) { die('<h1>Could not connect to MySQL: </h1>' . mysql_error());
   } echo '<h1>Connection OK</h1>'; mysql_close($link);
 //usleep(17000000);
?>

abbiamo messo il file chk.php nella root direcotry dei rispettivi web server. Lo script in bash è poi lanciato da un server collegato ad una linea ADSL 7Mb/s residenziale, non in una farm con connettività 100Mb/s. Per prima cosa verifichiamo che abbiamo connettività, facciamo un ping a google.it, siamo sicuri che al 99.99% il server è UP e la mancata risposta deriverà per altri fattori, fatto questo prendiamo il risultato e controlliamo che la risposta del PING sia soddisfacente e che nel momento di esecuzione dello script non ci sia un degrado di linea. Superati i controlli della linea ADSL da cui effettuiamo i check, tramite il comando "wget" scarichiamo il file chk.php, il quale per produrre l'HTML dovrà connettersi al DB, in qeusto modo risuciamo a controllare che l'instanza MYSQL è UP e che risponde in tempi acettabili, ora in base all'esito ci regoliamo di conseguenza:
  1. Il file viene scaricato, procediamo con il controllo del tempo impiegato per il download
  2. Il fine non viene scaricato, proviamo ad effettuare il riavvio del demone HTTPD
Nel caso uno decidiamo un tempo entro il quale i valori sono normali, superato questo tempo inviamo una mail indicando tutti i parametri, il ping verso google.it per capire lo stato della linea ADSL, il ping verso il server e tutto quello che riteniamo necessario, stessa cosa con l'SMS. Nel caso due apriamo una connessione SSH e da remoto lanciamo il comando per il restart del demone, i sistemi sono tutti CentoOS, quindi il comando è univoco "/etc/init.d/httpd restart", aspettiamo 5 secondi e vediamo se ora è possibile scaricare il file, ora ci troviamo di nuovo davanti a due possiblità:
  1. Il file viene scaricato
  2. Il fine non viene scaricato
Caso uno, inviamo solo una mail per avvisare che il servizio è garantito ma c'è stat bisogno del restart di APACHI, nel secondo caso prepariamo sia la MAIL che l'SMS per avvisare che il sistema è fermo. L'SMS lo troviamo più affidabile della mal, anche per copertura di rete, problemi con mail server, mailbox piena, ecc..., potrebbero esserci mille problemi per i quali non leggiamo la posta, ma un SMS è più immediato. Si seguito lo script utilizzato:

#!/bin/bash
# LANCIARE LO SCRIPT PASSANDOGLI 
# L'INDIRIZZO IP DA CONTROLLARE

ping google.it -c 2
if [ $? -eq 0 ]; then # SE HO CONNETTIVITA' PROSEGUO
  GPING=$(ping -c 2 google.it|awk -F"=" '{print $4}'|sed -e '/^$/d'|tail -1|awk -F\. '{print $1}')
  PINGSERVER=$(ping -c 2 $1|awk -F"=" '{print $4}'|sed -e '/^$/d'|tail -1|awk -F\. '{print $1}')

  # SE LA RETE E' LENTA ESCO DALLO SCRIPT
    if [ "`echo $GPING`" -gt "240" ]; then
    echo "IMPOSSIBILE VERIFICARE LO STATO DEI SERVER, RETE CERRETO GUIDI LENTA"
    else

#PREPARO LO SCRITP PHP PER L'INVIO DEGLI SMS
cat > /tmp/ERRORSMS.php << MOSO123
<?php
\$username="username";
\$password="password";
\$mittente="SERVER DOWN";
\$credito_terminato=10;
\$email="supporto@lbit-solution.it";
\$lunghezza=160;
\$server_credito_residuo="http://www.subitosms.it/gateway.php?username=".urlencode(\$username)."&password=".urlencode(\$password);
\$destinatario="+393391234567,+393491234567,+393397654321";
\$credito=trim(file_get_contents(\$server_credito_residuo));

if (\$credito=='non autorizzato') {
mail(\$email,
'Script di invio SMS',
"Lo script per l'invio degli SMS non funziona, forse hai sbagliato la password.",
"From: sms@lbit-solution.it");
echo "<meta http-equiv=\"Refresh\" content=\"0;URL=\$pagina_ko\" />";
}

\$credito=str_replace("credito:","",\$credito);

// Verifica il credito e avvisa in caso di credito in fase finale
if (\$credito<=\$credito_terminato) {
mail(\$email,
'Script di invio SMS - credito residuo',
"Lo script per l'invio ha un residuo di \$credito SMS.",
"From: sms@lbit-solution.it");

}

MOSO123
#FINE PREPARO LO SCRITP PHP PER L'INVIO DEGLI SMS

# VERIFICO CHE SIA STATO PASSATO L'INDIRIZZO IP DA CONTROLLARE
if [ -z $1 ]; then
  echo "SEI UN IDIOTA, QUESTO SCRIPT MANDA SMS"

cat > /tmp/alert_server.html <<DT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<title>IDIOTA USA SCRIPT</title>
<p>Un idiota si &egrave; collegato in SSH e sta lanciando lo script per il monitoraggio dei server di 
esercizio senza avergli passato il parametro INDIRIZZO IP allo script stesso. Se non ci fosse questo 
controllo ora andrebbero buttati diversi eurini guadagnati con il sudore, o quasi. Ora hai il coraggio 
di avvisare uno dei numeri in elenco per dirgli che hai fatto una cavolata?<br />
Domenico Tricarico 3391234567<br />
Roberto Massimi 3491234567<br />
Mirko Capasso 3397654321</p>
<p><b>$(hostname)</b> dice: <span >$(/usr/bin/fortune)</span></p>
DT
(cat <<EOCAT
Subject: IDIOTA CONNESSO
MIME-Version: 1.0
Content-Type: text/html
Content-Disposition: inline
From:$(hostname) <no-replay@lbit-solution.it>
Reply-To:Supporto LBiT<supporto@lbit-solution.it>
EOCAT
cat /tmp/alert_server.html) | /usr/sbin/sendmail supporto@lbit-solution.it

# HO INVIATO LA MAIL PERCHE' NON HAI PASSATO L'IP DA CONTROLLARE

  else

   time_sito=`(time -p wget http://$1/chk.php > /dev/null) 2>&1 | grep real|awk '{print $2}'|awk -F\. '{print $1}'`
   if [ -e chk.php ]; then # SE IL FILE ESISTE
     echo "FILE TROVATO, PROSEGUO CON I CONTROLLI SUL TEMPO DI DOWNLOAD"
       if [ "`echo $time_sito`" -gt "15" ]; then # VERIFICO IL TEMPO DI DOWNLOAD
        # IL DOWNLOAD DELLA PAGINA E' AVVENUTO IN TROPPO TEMPO

        echo "SERVER $1 LENTO"

cat >> /tmp/ERRORSMS.php << MOSO1232
\$testo="Server $1 eroga un pessimo servizio. Download page in $time_sito secondi ASSISTENZA ARUBA 05750501";
\$server_invio=\$server_credito_residuo.= "&testo=".urlencode(\$testo).
"&mitt=".urlencode(\$mittente).
"&dest=".urlencode(\$destinatario);
\$invio=trim(file_get_contents(\$server_invio));
?>
MOSO1232

    /usr/bin/php /tmp/ERRORSMS.php
    echo "INVO SMS IN CORSO"

cat > /tmp/alert_server.html <<DT2
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<title>Alert Server $1 down</title>
</head>
<body>
<h1 >$1 SERVIZIO SCADENTE</h1>
<h3>Il server sta erogando un pessimo servizio, verificare!</h3>

<p>Probabilmente il server $1 ha problemi, la rete da cui sto testando &egrave; perfettamente 
funzionante, riesco a raggiungere google in $(echo $GPING) ms e il server $1 in $($PINGSERVER) ms.<p>

<p>Intervenire subito sul server <b>$1</b> e contattare i seguenti riferimenti:<br />
Domenico Tricarico 3391234567<br />
Roberto Massimi 3491234567<br />
Mirko Capasso 3397654321</p>

<p>Se non &egrave; possibile accedere contattare <b>ASSISTENZA ARUBA <span >05750501</span></b><p>

<p><b>$(hostname)</b> dice: <span >$(/usr/bin/fortune)</span></p>
DT2

(cat <<EOCAT2
Subject: [$1] SERVER EROGA UN PESSIMO SERVIZIO
MIME-Version: 1.0
Content-Type: text/html
Content-Disposition: inline
From:$(hostname) <no-replay@lbit-solution.it>
To: Supporto LBiT<supporto@lbit-solution.it>
Reply-To:Supporto LBiT<supporto@lbit-solution.it>
EOCAT2
cat /tmp/alert_server.html) | /usr/sbin/sendmail supporto@lbit-solution.it
       echo "INVIO MAIL IN CORSO"
       rm /tmp/ERRORSMS.php
       rm /tmp/alert_server.html
       rm chk.php
      else # SE IL FILE ESISTE IL SERVER E' FUNZIONANTE
       echo "SERVER $1 REGOLARE"
       fi # FINE SE IL FILE ESISTE
      rm chk.php

    else # SE IL FILE NON ESISTE IL SERVER NON EROGA SERVIZIO O NON E' RAGGIUNGIBILE
    echo "SERVER $1 FERMO"
    echo "RESTART DEL DEMONE HTTPD SUL SERVER $1"
    ssh $1 "/etc/init.d/httpd restart"
    sleep 5
    time_sito=`(time -p wget http://$1/chk.php > /dev/null) 2>&1 | grep real|awk '{print $2}'|awk -F\. '{print $1}'`
     if [ -e chk.php ]; then
       echo "SERVER DI NUOVO ONLINE"
       # INVIO MAIL PER SERVER DI NUOVO ONLNE
cat > /tmp/alert_server.html <<DT3
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<title>APACHE RESTART</title>
</head>
<body>
<h1 >APACHE RESTART</h1>
<h3>Il server $1 &egrave; di nuovo online</h3>
<p>Probabilmente il server $1 aveva il demone APACHE down, dopo aver effettuato un restart &egrave; tornato nuovamente on-line e ora i servizi 
erogati sono nuovamente garantiti.<br />
La rete da cui sto testando &egrave; perfettamente funionante, riesco a raggiungere google in $(echo $GPING) ms.<p>

<p>Di seguito il risultato del comando uptime:<br />
$(ssh $1 "uptime")</p>

<p><b>$(hostname)</b> dice: <span >$(/usr/bin/fortune)</span></p>
DT3
(cat <<EOCAT3
Subject: [$1] RESTART APACHE
MIME-Version: 1.0
Content-Type: text/html
Content-Disposition: inline
From:$(hostname) <no-replay@lbit-solution.it>
To: Supporto LBiT<supporto@lbit-solution.it>
Reply-To:Supporto LBiT<supporto@lbit-solution.it>
EOCAT3
cat /tmp/alert_server.html) | /usr/sbin/sendmail supporto@lbit-solution.it
echo "INVIO MAIL IN CORSO"
# FINE INVIO MAIL PER SERVER DI NUOVO ONLNE
exit 0
fi
cat > /tmp/alert_server.html <<DT3
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<title>Alert Server $1 down</title>
</head>
<body>
<h1 >$1 SERVIZI NON EROGATI</h1>
<h3>Il $1 non sta erogando servizi, verificare!</h3>
<p>Probabilmente il server $1 &egrave; spento o non raggiungibile, la rete da cui sto testando &egrave; perfettamente 
funzionante, riesco a raggiungere google in $(echo $GPING) ms.<p>

<p>Intervenire subito sul server <b>$1</b> e contattare i seguenti riferimenti:<br />
Domenico Tricarico 3391234567<br />
Roberto Massimi 3491234567<br />
Mirko Capasso 3397654321</p><br />
<p>Se non &egrave; possibile accedere contattare <b>ASSISTENZA ARUBA <span >05750501</span></b><p>
<p><b>$(hostname)</b> dice: <span >$(/usr/bin/fortune)</span></p>
DT3
(cat <<EOCAT3
Subject: [$1] ALERT SERVER DOWN
MIME-Version: 1.0
Content-Type: text/html
Content-Disposition: inline
From:$(hostname) <no-replay@lbit-solution.it>
To:Supporto LBiT<supporto@lbit-solution.it>
Reply-To:Supporto LBiT<supporto@lbit-solution.it>
EOCAT3
cat /tmp/alert_server.html) | /usr/sbin/sendmail supporto@lbit-solution.it
echo "INVIO MAIL IN CORSO"

cat >> /tmp/ERRORSMS.php << MOSO1233
\$testo="Server $1 non raggiungibile, ASSISTENZA ARUBA 05750501";
\$server_invio=\$server_credito_residuo.= "&testo=".urlencode(\$testo).
"&mitt=".urlencode(\$mittente).
"&dest=".urlencode(\$destinatario);
\$invio=trim(file_get_contents(\$server_invio));
?>
MOSO1233
      /usr/bin/php /tmp/ERRORSMS.php
      echo "INVIO SMS IN CORSO"
      fi # CHIUDO SE ESISTE
    fi
  fi
fi

touch /tmp/hogirato

 Per finire mettiamo lo script in crontab:

02,12,22,32,42,52 * * * * /media/backup/check_server.sh 92.160.243.55
03,13,23,33,43,53 * * * * /media/backup/check_server.sh 95.160.243.56
04,14,24,34,44,54 * * * * /media/backup/check_server.sh 95.160.243.57
05,15,25,35,45,55 * * * * /media/backup/check_server.sh 95.160.243.58

Controllo temperatura server linux

Esigenza: controllare la temperatura di alcuni server linux.

Due delle macchine che compongono la'infrastuttura di backup sono allocate in una stanza non climatizzata, la temperatura non sale mai a livelli di guardia, comunque è sempre bene tenere sotto controllo la temperatura del processore.

Il comando "sensors" rileva i vari sensori prsenti nell'hardware della macchina, nel mio caso posso sfruttare la temperatura delle CPU, il seguente script prende un solo valore in considerazione. Difficilmente avremo una CPU a 28°C e una a 65°C.

Lo script prende la temperatura dal comando sensor e manipola l'output, ottiene la temperatura esterna tramite ClassMeteo nella pagina di Yahoo, questo per dare evidenza della situazione climatica; un esempio banale è quello i avere una temperatura esterna di 36°C e le CPU a 45°C, lo consideramo normale, ma avere l'esterna a -5°C e l'interna a 65°C dovrebbe farci pensare, soprattutto se le CPU non stanno lavorando, magari ci siamo solo dimenticati l'impianto di riscaldamento acceso e su una temperatura decisamente tropicale.

Effettuato il controllo, cercando la soglia massima otlre la quale deve far partire l'aert è di 55°C, la soglia massima consigliata dal produttore è di 65°C, per qeusto mi prendo un "margine" di 10°C, per dare il tempo di controllare in SSH e di intervenire in sede. 


#!/bin/bash
temp=$(sensors|grep Core|sed -e's/[^0-9.]//g' -e 's/^0//g'|tail -1|awk -F"." '{print $1}')
wget http://it.meteo.yahoo.com/italia/toscana/cerreto-guidi-12846264/
external=$(grep -i "<div temp-c \">" index.html |tr "<" "\n"| grep -i "day-temp-current temp-c"|sed -e 's/[^0-9]//g')
clear
echo "Temperatura interna: $temp gradi centigradi"
echo "Temperatura esterna: $external gradi centigradi"
if [ $temp -gt 55 ]; then

cat > /tmp/chktmp.eml <<DT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<title>Tempi di apertura sito</title>
<h1 >TEMPERATURA ALTA</h1>
<h2>La temperatura del server <b>$(hostname)</b> &egrave; di <span ><b>$(echo $temp) &deg; C</b></span>.</h2>
<p>La temperatura esterna &egrave; di <b>$(echo $external)&deg; C</b> rilevata da <a href="http://it.meteo.yahoo.com/italia/toscana/cerreto-guidi-12846264/">ClassMeteo</a>.</p>

<br />

<br />
<p>Rispondendo a questa mail contatterai il gruppo di supporto LBiT soluzioni informatiche.</p>
<p>Mail inviata da $(hostname).</p>

DT
(cat <<EOCAT
Subject: ALLARME TEMPERATURA $(echo $hostnama) $(echo $temp)
MIME-Version: 1.0E
Content-Type: text/html
Content-Disposition: inline
From:$(hostname).lbit-solution.it <no-replay@lbit-solution.it>
To: Gruppo Supporto LBiT soluzioni informatiche <supporto@lbit-solution.it>
EOCAT
cat /tmp/chktmp.eml) | /usr/sbin/sendmail supporto@lbit-solution.it amministrazione@lbit-solution.it
fi
rm -f index.htm*

Script Queue mail QMAIL

Come al solito pubblico un articolo dopo aver avuto delle particolari necessità, questa volta dovevo mettere sotto monitoraggio il mail server, qmail.
Succedeva che per quelche motivo il DNS server al quale puntavo non riconosceva alcuni domini, il problema diventa serio quando un cliente prende l'hosting da me e lascia la posta su un'altro provider, configuo dominio e tutto va bene, fin quando perà le mail che partivano dal mio server restavano in coda.
Ci ho messo un po a capire che la mancata consegna della posta fosse dovuta da un record DNS non esatto.
Modificando il file /etc/resolv.conf e mettendo in testa il DNS di google tutto filava liscio.
Vista la brutta esperienza, considerando che gran parte dell'hosting offerto ospita siti di commercio elettronico, o comunque aziendiali, ho deciso di mettere un semplice script che possa avvisarmi quanso c'è coda e quando le mail non vengono processate.


G4PLAY

#!/bin/bash

# Verifico le mail in CODA e in CODA NON PROCESSATE

# SE LA CODA (Q) E' MAGGIORE DI 1 E LA

# CODA NON PREOCESSATA (QNP) MAGGIORE DI 0

# INVIO UNA MAIL IN FORMATO HTML



DOMINIO="lbit-solution.it"

DESTINATARIO="supporto"

NOMEDEST="Supporto LBiT"

DIR="/var/monitoraggio/script"



# CODA ATTIVA

/var/qmail/bin/qmail-qstat |grep -v not|awk '{print $4}' > $DIR/queue



# MAIL IN CODA NON PROCESSATE

/var/qmail/bin/qmail-qstat |grep -i not|awk '{print $8}' > $DIR/queuen



Q=`cat $DIR/queue`

QNP=`cat $DIR/queuen`

if [ $(cat $DIR/queue) -gt "1" ] || [ $(cat $DIR/queuen) -gt "0" ]

then

cat > /tmp/alertQueue.html <<DT

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<meta http-equiv="content-type" content="text/html; charset=windows-1250">

<title>Alert filesystem</title>

</head>

<body>

<h1 >MAIL IN CODA VERIFICARE IL MAIL SERVER Q=$Q QNP=$QNP</h1>

<h3>Attenzione, il mail server non riesce a smaltire o a consegnare alcune mail </h3>

<p><a href="http://www.lbit-solution.it/monitoraggio/index.php">Pagina di monitoraggio</a></p>



<br />

Ci sono <b>$Q</b> mail in coda e <b>$QNP</b> mail non processate. <br />

<br />

<p>

Di seguito le mail in coda:<br />

$( /var/qmail/bin/qmail-qread|tr -d '\011'|sed -e :a -e '$!N;s/\nremote//;ta' -e 'P;D'|sed -e 's/</mittente: /g' -e 's/>/ destinatario:/g' | while read queue; do

echo "$queue <br />"

done)

</p>

<br />



<h5><a href="http://www.lbit-solution.it">Mail send by LBiT soluzioni informatiche</a></h5>



</body>

</html>

DT



(cat <<EOCAT

Subject: [$(hostname)] Queue Mali Alert Q $Q QNP $QNP

MIME-Version: 1.0

Content-Type: text/html

Content-Disposition: inline

From:$(hostname) <no-replay@$DOMINIO>

Reply-To:$NOMEDEST<$DESTINATARIO@$DOMINIO>

EOCAT

cat /tmp/alertQueue.html) | /usr/sbin/sendmail supporto@lbit-solution.it

rm -f /tmp/alertQueue.html



fi

Finito lo script è stato messo in crontab e gira ogni 5 minuti, devo dire che diversi provider esterni hanno dei tempi lentissimi nel ricevere la posta, questo banale script mi consente di offrire un servizio migliore e di accorgermi di eventuali problemi prima del cliente.

Script controllo filesystem

Negli ultimi mesi non ho postato nessun articolo, non per voglia ma per tempo.
Riprendo degli argomenti che volevo affrontare nei mesi scorsi ma non ho potuto, il controllo dei dischi con alert mail.
Come al solito nulla di complicato, scriviamo uno script che controlla lo spazio disco e, se inferiore ad una data percentuale, provvede ad in inviare una mail in formato HTML, nel contenuto della mail ci sarà anche il link ad una pagina di gestione per sistemi con IP DINAMICI.

Ecco il codice:

1 #!/bin/bash
2 # SCRIPT ELSAMU VPS
3 # FILESYSTEM /media/160 GIGA
4 ### CONFIG ####
5 FSCHK="/var/www/vhosts"
6 DSCHK="/dev/vzfs"
7 WEBPAGE=""
8 rm -f index.html
9 INTIP="`/sbin/ifconfig eth0 |grep -i inet|head -1|awk '{print $2}'|sed -e 's/addr://g'`"
10 EXTIP="`wget http://www.indirizzo-ip.com/;grep -i TITLE index.html |awk '{print $3}'|sed -e 's/<\/TITLE>//g'`"
11 SPACE=`df -h $DSCHK|awk '{print $5}'|tail -1|sed -e 's/%//g'`
12
13 #### INIZIO SCRIPT
14
15 if [ $SPACE -gt 85 ]
16   then
17 cat > /tmp/alert.html <<DT
18 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
19 <html>
20 <head>
21 <meta http-equiv="content-type" content="text/html; charset=windows-1250">
22 <title>Alert filesystem</title>
23 </head>
24 <body>
25 <h1 style="color: red">RISCHIO FILESYSTEM FULL</h1>
26 <h3>ATTENZIONE FILESYSTEM $SPACE %</h3>
27 <p>HOSTNAME: <b>`hostname`</b></p>
28 <p>PUBBLIC IP: <b>$EXTIP</b></p>
29 <p><a href=`echo "\"http://$EXTIP$WEBPAGE\""`>WEB  PAGE INFO SERVER </p></h5>
30
31
32 <p> <b>STATO FILESYSTEM:</b><br />
33 $(df -h $DSCHK|while read line;
34 do echo "$line <br />"
35 done) </p>
36
37 <p><b>LA DIRECTORY $FSCHK OCCUPA:</b><br />
38 $(du -sh $FSCHK|tail -1)
39 </p>
40
41 <p> <b>STATO FILESYSTEM GENERALE:</b><br />
42 $(df -h|while read line;
43 do echo "$line <br />"
44 done)  </p>
45
46 <br />
47 <h5><a href="http://www.lbit-solution.it">Mail send by LBiT soluzioni informatiche</a></h5>
48 </body>
49 </html>
50
51
52 DT
53
54 (cat <<EOCAT
55 Subject: [ELSAMU-VPS] File System Alert $SPACE
56 MIME-Version: 1.0
57 Content-Type: text/html
58 Content-Disposition: inline
59 EOCAT
60 cat /tmp/alert.html) | /usr/sbin/sendmail supporto@lbit-solution.it
61   rm -f /tmp/alert.html
62   rm -f index.html
63 echo "[$(date +'%F %H:%M:%S')] Filesystem alert - $(df -h $DSCHK|awk '{print $5}'|tail -1|sed -e 's/%//g')% in uso" >> /var/log/chkdsk.log
64 else
65 echo "[$(date +'%F %H:%M:%S')] Filesystem nella norma - $(df -h $DSCHK|awk '{print $5}'|tail -1|sed -e 's/%//g')% in uso" >> /var/log/chkdsk.log
66 fi
67
 


Ora basta mettere in crontab lo script e sperare che il disco non si saturi mai:
00 * * * * /var/script/chkdisk.sh

Per personalizzare lo script basta cambiare le variabili alla riga 5, 6 e7 e la percentuale oltre la quale deve partire la mail a riga 15; alla riga 60 troviamo invece l'indirizzo al quale inviare la mail.

Bash e mio figlio

Mio figlio non mi lascia lavorare, ha ragione prima dobbiamo giocare con loro e poi pensare al nostro lavoro.
Il pinguino mi aiuta a distrarlo mentre finisco alcune pratiche urgenti:

sleep 1;clear;echo ciao SAMUEL|cowsay ; sleep 1;clear;echo "ALLONTANATSI DALLA LINEA GIALLA"|cowsay ;sleep 2;sl;sl;clear;echo "TRENO IN TRANSITO AL BINARIO 1"|cowsay ;sleep 2; sl -F; sl -l;sl -e

Se poi gli mettiamo un loop abbiamo un nuovo gioco!
  while true; do sleep 1;clear;echo ciao SAMUEL|cowsay ; sleep 1;clear;echo "ALLONTANATSI DALLA LINEA GIALLA"|cowsay ;sleep 2;sl;sl;clear;echo "TRENO IN TRANSITO AL BINARIO 1"|cowsay ;sleep 2; sl -F; sl -l;sl -e; done

Un simpatico treno che attraversa il nostro schermo, una mucca controllore! Con un pò di fantasia possiamo farlo diventare un vero gioco, magari con frasi randomiche.

Google Maps sentieri e natura

Cosa si sta inventando di nuovo GOOGLE? Dopo Maps, Street View, Traffico  arrivano i sentieri, si si proprio i sentieri.
Googla si sta tuffando nella natura per poter fotografare tutto quello che ci circonda, in qesto modo comodamente dal nostro PC potremo vedere posti lontanissimi e valutare le nostre future mete, darà la possibilità di guardare luoghi irraggiungibili per molti.
Grande Big G



URL SEO OPENCART ARUBA

Uno delle prime operazioni da fare per ottimizzare il nostro sito di e-commerce è creare delle URL SEO-friendly, ma usando OpenCart su server Linux Aruba potremo avere dei problemini, ovvero ricevere la schermata di ERROR 500 e sito DOWN!

Niente di preoccupante, OpenCart prevede di base la possibilità di usare dei link SEO friendly, o URL semplici, in effetti nel pacchetto d'installazione troviamo un file .htaccess.txt, ed è proprio lui che sui server Aruba ci fa restituire error 500.

Per risolvere questo basta modificare il file .htaccess lasciando solo queste entry:

#Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule ^(.*)$ ./index.php/$1 [L]
RewriteRule ^(.*)\?*$ index.php?_route_=$1 [L,QSA]


Ricordiamoci dal pannello amministrativo, su SISTEMA/IMPOSTAZIONI/SERVER, e spostiamo il flag su SI di Usa URL SEO.

Per ogni categoria, prodotto e pagina dobbiamo valorizzare il campo URL SEO come nell'esempio:
processori_amd per la categoria Processori AMD, cosi verrà costruito un link del tipo
http://www.tuttoperilpc.it/Informatica


Cancellare i riassunti da wordpress

A volte i riassunti prodotti dai plugin di wordpress non sempre facilitano la gestione del sito, anzi a volte ci obbligano a rimuovere l'html.


Inizialmente rimuovevo il codice html da tutti i riassunti che davano problemi, con il tempo gli articoli aumentiavano e i riassunti errati rendevano il sito non fruibile, per risolvere basta fare l'update di una tabella, posto il codice PHP in modo da poter fare una pagina da poter richiamare con il browser:


<?php
print "HO CANCELLATO I RIASSUNTI DI GIANDIEGO MARIGO \n";
$conn = mysql_connect("62.149.150.95", "utente", "password");
mysql_select_db('photogulp');
$sql=" UPDATE `photogulp`.`PHOTOGULP_posts` SET `post_excerpt` = '' WHERE `PHOTOGULP_posts`.`post_author` =62";
mysql_query($sql);
mysql_close($conn)
?>
<br> 
 
 

Buon compleanno GOOGLE



Buon compleanno big G, oggi compie 13 anni di gloriosa vita, credo che ben pochi progetti in rete abbiano avuto una vita cosi lunga.
Nasce come motore di ricerca e ora "alberga" nei nostri telefoni cellulari, ci dice dove andare snobbando il Tom Tom, archivia i nostri documenti, la posta, ci aiuta realizzare i siti, ci fa navigare con CHROME, ospita i nostri blog, possiamo videochiamare, ecc... Ma quante cose fa? TUTTO! E per ora dopo Buzz e arriva GOOGLE +1, il social network che farà tremare FACEBOOK.

Auguroni alla società numero 1

Rotazione banner con PHP

Oggi posto un pratico e banale codice PHP per inserire nelle proprie pagine dei banner a rotazione.
Questo torna comodo quando non vogliamo riempire le pagine del nostro sito con decine di banner, inseriamo il codice sottoriportato e avremo la rotazione delle nostre campagne pubblicitarie, un po come google adsense. Io personalmente uso diversi siti di affiliazione e nel caso specifico ZANOX non ha questa comoda funzione, a questo ci aiuta PHP.

Apportare modifiche è semplice, settare quanti banner vogliamo inserire alla riga 2 sostituendo il valore 9 con qello desiderato; ogni elsif è un banner e il codice va inserito tra gli apici della "print", semplice.

Il risultato è la rotazione di banner randomici ad ogni visualizzazione della pagina, quando avrò tempo vorrei inserire del codice java per farli ruotare senza il refresh della pagina in visualizzazione.


CODICE PHP:
<?php
$random = random(1,9);
if ($random == 1) //Commento per Codice 1
print '<a target="_blank" href="http://ad.zanox.com/ppc/?19502843C1575357854T"><img src="http://ad.zanox.com/ppv/?19502843C1575357854" align="bottom" width="468" height="60" border="0" hspace="1" alt="InMediolanum Direct - Image Banner 468 x 60"></a>';

elseif ($random == 2) //Commento per Codice 2
print '<a target="_blank" href="http://ad.zanox.com/ppc/?18982653C558409180T"><img src="http://ad.zanox.com/ppv/?18982653C558409180" align="bottom" width="468" height="60" border="0" hspace="1" alt="Prenota online i voli economici eDreams!"></a>';

elseif ($random == 3) 
print '<a target="_blank" href="http://ad.zanox.com/ppc/?19502859C320315674T"><img src="http://ad.zanox.com/ppv/?19502859C320315674" align="bottom" width="468" height="60" border="0" hspace="1" alt="New Direct Image Banner 468x60"></a>';

elseif ($random == 4) 
print '<img src="http://ad.zanox.com/ppv/?19502861C750326682" align="bottom" width="1" height="1" border="0" hspace="1"><script language="javascript" src="http://ad.zanox.com/ppv/images/programs/flash_load/flash_loader_ng.js"></script><script type="text/javascript">zxFlash("http://static.it.groupon-content.net/affiliate/dynamic_banner/cid_dynamic_banner_groupon_468x60_plain_it_IT_zanox.swf", "", 468, 60, "opaque", "http://ad.zanox.com/ppc/?19502861C750326682&ULP=", "XXX");</script>';

elseif ($random == 5) 
print '<a target="_blank" href="http://ad.zanox.com/ppc/?19502866C1336435436T"><img src="http://ad.zanox.com/ppv/?19502866C1336435436" align="bottom" width="468" height="60" border="0" hspace="1" alt="New Image Banner 468 x 60"></a>';

elseif ($random == 6) 
print '<a target="_blank" href="http://ad.zanox.com/ppc/?19502867C1668787694T"><img src="http://ad.zanox.com/ppv/?19502867C1668787694" align="bottom" border="0" hspace="1" alt="promozione Pr&#65533;natal"></a>';

elseif ($random == 7)
print '<img src="http://ad.zanox.com/ppv/?19502868C1938169590" align="bottom" width="1" height="1" border="0" hspace="1"><script src="http://bs.serving-sys.com/BurstingPipe/adServer.bs?cn=rsb&c=28&pli=2292040&PluID=0&w=468&h=60&ord=[timestamp]&ucm=true&ncu=http://ad.zanox.com/ppc/%3F19502868C1938169590%26ULP%3D"></script><noscript><a target="_blank" href="http://ad.zanox.com/ppc/?19502868C1938169590&ULP=http://bs.serving-sys.com/BurstingPipe/adServer.bs?cn=brd&FlightID=2292040&Page=&PluID=0&Pos=6023" target="_blank"><img src="http://bs.serving-sys.com/BurstingPipe/adServer.bs?cn=bsr&FlightID=2292040&Page=&PluID=0&Pos=6023" border=0 width=468 height=60></a></noscript>';

elseif ($random == 8)
print '<a target="_blank" href="http://ad.zanox.com/ppc/?19502874C1192392898T"><img src="http://ad.zanox.com/ppv/?19502874C1192392898" align="bottom" width="468" height="60" border="0" hspace="1" alt="468x60.gif"></a>';

elseif ($random == 9)
print '<a target="_blank" href="http://ad.zanox.com/ppc/?19502873C1243644210T"><img src="http://ad.zanox.com/ppv/?19502873C1243644210" align="bottom" border="0" hspace="1" alt="7 mega 468x60"></a>';
?>

Redirect in javascript con countdown

Come al solito cercavo di migliorare il sito PHOTOGULP.it, questa volta avevo la necessità di inserire un redirect da alcuni post verso le pagine del FORUM.
Se non mi complico la vita non provo gusto nelle cose che faccio, quindi volevo inserire il conto alla rovescia prima del redirect, questo per avvisare il lettore dandogli quindi la possibilità di cliccare su altri link.
La soluzione arriva usando javascript:


<strong><script language="javascript" type="text/javascript">
    sito = "<?php the_syndication_permalink(); ?>";  // sito
    sec = 20;                                         // numero di secondi prima del redirect
    var cdID = window.setInterval('nonsochenomedare();', 1000);
     
    function nonsochenomedare ( )
    {
        var m = (sec == 1) ? "Manca 1 secondo" : "Mancano " + sec + " secondi";
        m += " al redirect verso <?php the_title(); ?> sul forum PHOTGULP.it";
        if (document.all)
        {
            document.all['countdown'].innerHTML = m;
        }
        else
        {
            document.getElementById('countdown').innerHTML = m;
        }
        if (sec == 0)
        {
            window.location = sito;
            window.clearInterval(cdID);
        }
        --sec;
    }
     
    </script></strong> 
 
 
Per postare del codice negli articoli, codice php, html, javascript o altro, potete andare sulla pagina http://xzfv.appspot.com/s/format.html

Emilio Stella - Alle case popolari

Vi consiglio un video da guardare di Emilio Stella, "Alle case popolari".


OSTIA BEACH Max Animazione radio globo video ufficioso ballo

Sullla parodia di Saxo Beat fatta da Radio Globo hanno realizzato questo simpatico video:


Buon compleanno Linux, 20 anni

Oggi è il compleanno di Linux, compie 20 anni.
Grazie a Linus Torvald che il 25 agosto del 1991 mandò in rete il seguente messaggio:
Linus Torvald di qualche anno fa
Hello everybody out there. I’m doing a (free) operating system, just a hobby, won’t be big and professional
oggi tutti possiamo beneficiare del sistema operativo Linux.
Tutto ebbe inizio nella stanzetta incasinata di un giovane ragazzo di Helsinki, appunto Linus Torvalds il 25 agosto 1991. Linux è poi cresciuto fino a diventare il più grande progetto collaborativo nella storia del mondo. È iniziato come un’ideologia comune tra alcuni sviluppatori di software che ritenevano che il codice sorgente dovesse essere condiviso liberamente.  
Linux e' un sistema operativo libero rilasciato con licenza GPL (General Public License) e sviluppato integrando parti del progetto GNU (Gnu is not Unix), altro progetto libero avviato negli anni 80 da Richard Stallman. Quest'ultimo negli anni ne ha poi rivendicato parte della creazione al punto di ottenere la denominazione di GNU/Linux.
Sviluppato sul modello Unix (lo stesso degli OS Apple, decisamente più costosi), Linux negli anni e' diventata un'icona innanzitutto per i sostenitori del software libero oltre che una valida alternativa a Windows. Ma Linux non e' soltanto un sistema operativo per utenti. Grazie alla liberta' di utilizzo, attualmente e' montato su circa il 50% dei server mondiali e installato sui 10 computer piu' veloci al mondo.

Tanti Auguri Linux, da ogni angolo del mondo e anche da chi veniva definito il peggior nemico: Windows. Microsoft sceglie un modo originale e simpatico per augurare al pinguino Tux lunga vita, un video inviato a Linux Foundation che decide a sua volta di pubblicarlo attraverso You Tube.




Rap Italiano Dust Impatto One Luv 2011 (Prod. Dust Impatto)



Scarica il nuovo album X dal sito www.impattoverbale.it, è in FREE DOWLOAD

L'abbandono di un cane FERRAFILM

Titolo con link al sito originale wordpress

Oggi volevo modificare i titoli del sito PHOTOGULP.it inserendo dei link.
PHOTOGULP.it sia un blog che un aggregatore di notizie, prende i post da altre fonti autorizzate e quindi volevo inserire il link del post originale nel titolo del post presente su POTOGULP.it.
Questo è possibile se usiamo il plugin per sindacare i post, ecco il codice da sostituire nel file single.php:




         <!-- TITOLO CON PERMALINK-->

        <div id="post-<?php the_ID(); ?>" <?php if (function_exists("post_class")) post_class(); else print 'class="post"'; ?>>

           <?php if (!get_post_meta($post->ID, 'hide_title', true)): ?><h2 class="post-title">

           <?php if (is_syndicated()) : ?>

               <a href="<?php the_syndication_permalink(); ?>" target="_blank"><?php endif; ?><?php the_title(); ?>

                   <?php if (is_syndicated()) : ?></a><?php endif; ?>

               </h2><?php endif; ?>

         <!-- TITOLO CON PERMALINK-->


Sostituirlo ovviamente al codice già presente altrimenti ci ritroveremo con due titoli.
LBiT soluzioni informatiche

Link and Search

Solo lei

Solo lei ha quel che voglio

So di esser pronto ed è già da un pò che ci penso ma tutto quel che so è che so bene con lei ma non capisco cosa intende fare dove vorrà arrivare. Non mi ha mai visto prima ma ora al mondo ci siamo solo io e lei, la conosco da un minuto l'ho appena trovata e già l'ho perduta resta una sconosciuta, un mistero e chissà se è vero quel che i suoi occhi mi stanno dicendo di lei, io lo spero e sta volta è per davvero e tutto questo perchè se puoi io so... può lasciarsi andare e l'accompagnerò e domani ti giuro che me ne andrò può lasciarsi andare e l'accompagnerò e poi ti giuro che sparirò...
Solo lei ha quel che voglio e sono io ciò che sta cercando.
Questa notte potrei darle il mondo potrei darle tutto ciò che cerca ciò di cui ha bisogno quindi molla il tipo che è con te o mi perderai, potresti non rivedermi mai più non si sa mai, non sa cosa sta rischiando pensa che stia scherzando ma sono io ciò che sta cercando, no di sicuro l'uomo che è con lei perchè questa serata spero l'abbia solo accompagnata, mi servon due minuti ma ti assicuro che verrà e questa notte durerà un'eternità, e il mondo gira solo perchè ora c'è lei solo per il suo sguardo che mi fa prendere il volo, muoio, la conosco appena e già vivo per ogni suo respiro ti giuro non ti prendo in giro e mentre l'ammiro mi accorgo quanto sia stupenda e hai sbagliato se pensi che m'arrenda...
Solo lei ha quel che voglio e sono io ciò che sta cercando.
Il mio intuito mi ha spinto e solo ora capisco perchè come un druido ho il fluido che fa per lei non conta quanto sia durato ma che sia stato qualcosa per cui vale la pena d'aver vissuto e quindi lascio che la storia abbia il suo corso naturale ma ti prego fammi capire perchè sto male perchè so che domani io mi sveglierò e sarò ancor del suo profumo intriso dal suo sorriso ucciso ma io sarò con la mia donna e lei col suo uomo visto che ho scoperto che è l'unica lei è la sola....
Solo lei ha quel che voglio e sono io ciò che sta cercando.

top