Microsoft SQL – Database in AAG – Abilitiamo o disabilitiamo servizi Windows sui nodi

Quella del cluster database di tipo AAG (Always-on Availability Group) è una delle configurazioni più resilienti di SQL e tramite una configurazione a nodo 1+N che se bilanciata bene permette una grossa resilienza ed un importante uptime.

Introduzione

Nell’AAG, uno dei nodi è sempre il primario, i “+N” (che potrebbe essere uno o molteplici) rimangono in standby con una replica puntuale dei DB. Una delle caratteristiche più interessanti della configurazione AAG è il failover automatico, che consiste nel cambio ruolo automatico a fronte di un problema tecnico. In questo scenario potrebbe essere necessario attivare dei servizi ancillari alla macchina, come ad esempio uno schedulatore esterno (es IWS), uno strumento di file transfer o un qualsiasi agent.

Esempio di TSQL per Avviare o Arrestare dinamicamente un servizio in base al nodo in cui sta girando l’istanza

di seguito, un piccolo POC con un esempio di TSQL per avviare o disabilitare un servizio a fronte di un cambio ruolo di SQL:

DECLARE @primreplica VARCHAR(100);
DECLARE @ServiceName VARCHAR(128) = 'NOMESERVIZIO';
DECLARE @Status VARCHAR(MAX);

    DECLARE @ServicesStatus TABLE
    (
        Status VARCHAR(50)
    );

SELECT @primreplica = s.primary_replica
FROM sys.dm_hadr_availability_group_states s
    JOIN sys.availability_groups ag
        ON ag.group_id = s.group_id;

-- se dove sto girando è primario
IF UPPER(@primreplica) = UPPER(@@SERVERNAME)
BEGIN

    INSERT @ServicesStatus
    EXEC xp_servicecontrol N'QUERYSTATE', @ServiceName;

    SELECT @Status = Status
    FROM @ServicesStatus;
    --select @Status

    IF @Status <> 'Running.'
    BEGIN
        EXEC xp_servicecontrol N'Start', @ServiceName;
    END;

END;

ELSE
BEGIN
    INSERT @ServicesStatus
    EXEC xp_servicecontrol N'QUERYSTATE', @ServiceName;

    SELECT @Status = Status
    FROM @ServicesStatus;
    --select @Status

    IF @Status = 'Running.'
    BEGIN
        EXEC xp_servicecontrol N'Stop', @ServiceName;
    END;

END;

Personalmente, l’ho schedulato in un job SQL sempre attivo su tutti i nodi (lo stesso JOB contiene lo statement per abilitare o disabilitare i JOB SQL).

Andiamo un poco più in drill-down:
Tramite la select di seguito riportata, stabilisco se sto girando sulla replica primaria o sul secondario, andando a confrontare il nome del server su cui sta girando l’istanza (tramite la funzione SQL @@SERVERNAME) ed il nome della replica primaria sulle tabelle di sistema che regolano l’AAG:

SELECT @primreplica = s.primary_replica
FROM sys.dm_hadr_availability_group_states s
    JOIN sys.availability_groups ag
        ON ag.group_id = s.group_id;

-- se dove sto girando è primario
IF UPPER(@primreplica) = UPPER(@@SERVERNAME)

Con un semplice ciclo IF/ELSE tramite una tabella di appoggio e la StoreProcedure EXEC xp_servicecontrol determino se il servizio sta girando o meno ed in base alla risposta ed al server, avvio o disabilito il servizio:

INSERT @ServicesStatus
    EXEC xp_servicecontrol N'QUERYSTATE', @ServiceName;

    SELECT @Status = Status
    FROM @ServicesStatus;
    --select @Status

    IF @Status <> 'Running.'
    BEGIN
        EXEC xp_servicecontrol N'Start', @ServiceName;
    END;

Sintassi di xp_servicecontrol

EXEC xp_servicecontrol ‘Querystat|Start|Stop’,’servicename’

La store in oggetto accetta due parametri, il primo è l’operazione da svolgere:

  • Querystat – Restituisce lo stato di un servizio.
  • Start – Avvia un servizio.
  • Stop  – Arresta un servizio.

Il secondo, il nome del servizio.

Enjoy!

Scarichiamo su una tabella MS-SQL i dati degli utenti Active Directory leggendoli sempre da una tabella

Se fai il sistemista e ti diverti a fare reportistica ed incrociare dati tra gli applicativi aziendali e Active Directory, questo è lo script che fa per te.

Lo script powershell sfrutta i seguenti CMDlet:
DBAtools (https://dbatools.io/)
GetADUSER di Microsoft (https://4sysops.com/wiki/how-to-install-the-powershell-active-directory-module/)

Lo script è stato customizzato per essere configurato facilmente e l’ho creato per le mie esigenze.

In breve lo script:
– Legge una tabella con le utenze AD;
– Crea se non esiste la Tabella coi dati di AD
– Interroga AD e memorizza le info in una nuova tabella

Io metto sempre Integrated Security = True per usare l’identity SQL di chi esegue lo script.

$SQLDB = 'IP DEL DB'
$DB = 'NomeDatabase'
$TABLE = 'Tabella da scrivere'
$TABLESRC = 'Tabella da leggere'

$connString = "Server = " + $SQLDB + "; Database = " + $DB +  "; Integrated Security = True"
$QueryText = "SELECT [UTENZAACTIVEDIRECTORY] FROM " + $DB + ".[dbo]." + $TABLESRC

$SqlConnection = new-object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = $connString
$SqlCommand = $SqlConnection.CreateCommand()

$SqlCommand.CommandText = $QueryText

$DataAdapter = new-object System.Data.SqlClient.SqlDataAdapter $SqlCommand
$dataset = new-object System.Data.Dataset
$DataAdapter.Fill($dataset)

$dataset.Tables[0] | ForEach {

$DataTable = Get-ADUser -identity $_.matricola.Trim() -Properties * |select samaccountname , surname, givenname, mail ,department, enabled |Where-Object {$_.LastLogonDate -ge (get-date).adddays(-400)} | ConvertTo-DbaDataTable
Write-DbaDataTable -SqlInstance $SQLDB -Database $DB -InputObject $DataTable -Table $TABLE -AutoCreateTable
}

Ovviamente è un esempio, con Get-ADUser possono essere fatte centinaia di altre operazioni. Inoltre lo script può essere schedulato su un server, eseguirlo in interattivo o inserirlo in un JOB SQL per un report.

Chiamare da un CL IBMi uno script SH e ricevere un output da esso

CLP (Control Language Program) è un linguaggio di scripting eccezionalmente potente che permette di automatizzare operazioni su IBM-i (conosciuto anche come AS400).

Seppur potente, non copre proprio tutto tutto, e spesso va affiancato ad altri strumenti quali script SH *nix-like, che permette a chi viene da sistemi Linux o Unix di poter creare cose molto interessanti.

Qui di seguito un esempio di programma che intercetta l’output di uno script SH che può essere utilizzato come variabile all’interno di un programma CLP:

PREMESSA: sulla macchina deve essere presente 5770-SS1 – Portable Application Solutions Environment.

Per intercettare il STDOUT va creata una variabile di sistema tramite il comando:

ADDENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT)  VALUE(STDOUT) LEVEL(*JOB)

Esempio di programma:

PGM                                               
DCLF       FILE(QTEMP/O1)                         
DLTF       FILE(QTEMP/O1)                         
MONMSG     MSGID(CPF2105)                         
CRTPF      FILE(QTEMP/O1) RCDLEN(1000)            
OVRDBF     FILE(STDOUT) TOFILE(QTEMP/O1)          
STRQSH     CMD('SH path dello script')
DLTOVR     FILE(*ALL)                             
RCVF                                              
MONMSG     MSGID(CPF0864)                         
SNDPGMMSG  MSG(&O1)  
ENDPGM                                            

Questo esempio:
– scrive sul file QTEMP/O1 tramite OVRDBF l’output dello script SH
– tramite RCVF del file QTEMP/O1 può essere letto il campo appena scritto come variabile &O1

Letteratura a supporto

https://www.ibm.com/docs/en/i/7.2?topic=reference-calling-qshell-commands-from-i-command-line

https://www.ibm.com/docs/en/i/7.3?topic=i-installing-pase

LifeHack – Trasformiamo il sensore della porta WIFI in un telecomando per automazione domotica

Ciao a tutti oggi vi mostreremo come trasformare un economico sensore da porta in un telecomando per automazione wifi.

Di seguito il link al video: https://youtu.be/ppTtRBeBr2c

Normalmente questi sensori vengono applicati a porte e finestre per notificare l’apertura/chiusura o eventualmente per funzionare da trigger per automatizzare l’accensione di una luce o come antifurto.

Il sensore che ho acquistato è molto economico (circa 11 euro) ed è acquistabile su Amazon al seguente link: https://amzn.to/3s7M8Xp

Io uso prettamente apparati Tuya (SmartLife), la stessa procedura può essere svolta anche su Sonoff ed altri. il funzionamento è il medesimo.

Nella parte fissa del sensore (quella che per intenderci è dotata di batterie) è presente un componente chiamato “contatto REED”. Questo non è altro che un interruttore a lamina (normalmente aperto) che si chiude in presenza di un campo magnetico.

Facendo una rapida prova con il test impostato su continuità, possiamo osservare che avvicinando il magnete, il REED si chiude come un pulsante.

Armandoci di buona pazienza e di un saldatore, andiamo a rimuovere il REED (conservandolo magari per un futuro uso) e sostituiamolo con un pulsante a nostra scelta. io ne avevo uno di recupero simile a quello di reset, che ho spostato per usare il pulsante originale come trigger.

Ecco il circuito modificato

Una rapida prova prima di richiudere tutto

Infine la versione assemblata!

Ovviamente il tasto ora è da configurare sulla piattaforma del produttore (SmartLife, Ewelink, ecc ecc), oppure sull’assistente vocale preferito.

Le applicazioni sono molteplici, è possibile usarlo come campanello, come telecomando per accendere e spegnere dispositivi domotici, ecc ecc.

Kodi su Firestick – Canali del Digitale Terrestre

UPDATE 20210922 – Pubblicato il video sul canale Youtube: https://youtu.be/-4pluvobJG0

La Firestick Amazon è una vera e propria rivoluzione copernicana.
Questo articolo illustrerà come installare Kodi e gli addon necessari per vedere i canali del Digitale Terrestre.

La procedura è legale solamente se viene utilizzata per vedere canali in chiaro.

Per prima cosa abilitiamo da impostazioni > La mia Fire TV

Opzioni Sviluppatore

e mettiamo su ON le Applicazioni da fonti sconosciute

La fire chiederà di confermare l’opzione.

Attenzione: L’applicazione che vi indicheremo è abbastanza sicura e collaudata. Installate con giudizio le applicazioni esterne allo store. Una applicazione contenente un componente corrotto o virato potrebbe compromettere la stick!

Una volta abilitata la funzione, andremo ad installare il browser “Downloader” da Applicazioni > Categorie > Utility.

“Downloader” permette di scaricare da internet facilmente file sulla firestick

Terminata l’installazione dobbiamo lanciare la APP tramite la Homepage di FireStick

Aperta la mappa del software va cliccando sul campo di input

inseriremo l’indirizzo http://www.kodi.tv/download

Quando la pagina si caricherà sulla pagina richiesta

Va cercato il link della applicazione per Android

e scaricata la versione per ARM a 32 bit

una volta scaricato il file, partirà automaticamente l’installer

Scorrendo sulla mappa, apparirà il tasto Install

Premendolo partirà la vera e propria installazione. Una volta terminata l’installazione, sarà possibile aprire Kodi.

Lanciato Kodi, va aperta la mappa delle impostazioni per aggiungere una fonte da cui scaricare gli Add-ons

clicchiamo su File Manager

e su Add Source

Dalla mappa Add File Source va cliccato su <None>

inserito l’indirizzo https://worldlivetv.github.io/repo

e dato un nome parlante alla sorgente nel campo Enter a name for this media source

Aggiunta la Source, va selezionato Add-ons

selezionato Install from zip file

per motivi di sicurezza, l’installazione di add-ons esterni è inibito.
Va modificato il parametro premendo il tasto Settings

sotto Add-ons va abilitato Unknown source

Dato che andremo ad inserire un add-on sicuro, premere si.

Tornato sulla mappa, selezioneremo il repository con il nome parlante indicato su Add File Source

e scaricheremo/installeremo il file ZIP.

Quando apparirà il popup

Sara possibile accedere da Add-ons al repository di WorldLive TV

Da qui, da Video Add-ons

Dovremo selezionare World Live TV Helper

ed installarlo.

Terminata l’installazione, Kodi ci informerà con un popup che il componente richiesto è stato installato.

Selezioniamo poi dalla homepage di Kodi Add-ons

Video Add-ons

World Live TV Helper

Selezioniamo Select List

e procediamo con l’installazione dell’ultimo componente necessario, il PVR IPTV Simple Client indispensabile per avere l’elenco dei canali sulla voce TV della Homepage

Infine, dobbiamo selezionare dall’elenco FTA

Una volta installato tutto, sarà possibile goderci i canali del Digitale terrestre senza dover usare un decoder o una antenna tv

Enjoy!

tommy@madlabs.org

VBSCRIPT – Zippare ed Unzippare con 7z

In ambito sistemistico, a volte è utile avere tra le proprie armi una funzione per lavorare con i file ZIP. vi allego un comodo esempio da includere nei vostri script

Chiamata alla funzione

    ReturnCode = UnZip(“w:\file*.zip”, ”W:\CartellaOut\”)
    WScript.Echo ”ZIP ” & returnCode

    ReturnCode = Zip(“w:\file*.txt”, ”W:\CartellaOut\file.zip”)
    WScript.Echo ”ZIP ” & returnCode

Ponendo come riportato qui sopra, la funzione restituisce il return code.

Codice di Esempio

Le funzioni sono due: zip ed unzip

Function Zip(sFile,sArchiveName)

  Set oFSO = WScript.CreateObject("Scripting.FileSystemObject")
  Set oShell = WScript.CreateObject("Wscript.Shell")

  '--------Find Working Directory--------
  aScriptFilename = Split(Wscript.ScriptFullName, "\")
  sScriptFilename = aScriptFileName(Ubound(aScriptFilename))
  sWorkingDirectory = Replace(Wscript.ScriptFullName, sScriptFilename, "")
  '--------------------------------------

  '-------Ensure we can find 7z.exe------
  If oFSO.FileExists(sWorkingDirectory & "\" & "7z.exe") Then
    s7zLocation = ""
  ElseIf oFSO.FileExists("C:\Program Files\7-Zip\7z.exe") Then
    s7zLocation = "C:\Program Files\7-Zip\"
  Else
    Zip = "Error: Couldn't find 7z.exe"
    Exit Function
  End If
  '--------------------------------------

  oShell.Run """" & s7zLocation & "7z.exe"" a -tzip -y """ & sArchiveName & """ " _
  & sFile, 0, True   

  If oFSO.FileExists(sArchiveName) Then
    Zip = 1
  Else
    Zip = "Error: Archive Creation Failed."
  End If
End Function

Function UnZip(sArchiveName,sLocation)

  Set oFSO = WScript.CreateObject("Scripting.FileSystemObject")
  Set oShell = WScript.CreateObject("Wscript.Shell")

  '--------Find Working Directory--------
  aScriptFilename = Split(Wscript.ScriptFullName, "\")
  sScriptFilename = aScriptFileName(Ubound(aScriptFilename))
  sWorkingDirectory = Replace(Wscript.ScriptFullName, sScriptFilename, "")
  '--------------------------------------

  '-------Ensure we can find 7z.exe------
  If oFSO.FileExists(sWorkingDirectory & "\" & "7z.exe") Then
    s7zLocation = ""
  ElseIf oFSO.FileExists("C:\Program Files\7-Zip\7z.exe") Then
    s7zLocation = "C:\Program Files\7-Zip\"
  Else
    UnZip = "Error: Couldn't find 7z.exe"
    Exit Function
  End If
  '--------------------------------------

  '-Ensure we can find archive to uncompress-
  If Not oFSO.FileExists(sArchiveName) Then
    UnZip = "Error: File Not Found."
    Exit Function
  End If
  '--------------------------------------

  oShell.Run """" & s7zLocation & "7z.exe"" e -y -o""" & sLocation & """ """ & _
  sArchiveName & """", 0, True
  UnZip = 1
End Function

Una GUI per i nostri script VBScript

Esempio di GUI

VBScript sta per Visual Basic Scripting ed è come dice il nome un linguaggio di scripting multi-purpose. Questo è un derivato diretto di Visual Basic, ed è usato come sostituto, integrazione o appoggio per i file batch di MS-DOS .

Come tutti i linguaggi di scripting, non ha GUI nativa. Ma con un piccolo amico, l’HTA (Hypertext for Application) è possibile creare delle vere e proprie applicazioni =)

Un HTA non è altro che un file HTML arricchito con uno script VBS. Possono essere aggiunti JS, CSS, popup, campi di input ed altri elementi utili per creare un capolavoro.

Questo è un esempio di applicazione con tabs:

<html>
      <head>
            <title>Questa è una prova di GUI per gli script VBScript</title>
            <link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css" />
            <script language="javascript" src="http://code.jquery.com/jquery-1.10.2.js" type="text/javascript"></script>
            <script language="javascript" src="http://code.jquery.com/ui/1.10.4/jquery-ui.js" type="text/javascript"></script>
            <script language="javascript">
                  try {
                        self.resizeTo(1030, 600);
                   } catch(e) {
                   }
            </script>
            <hta:application
                  SINGLEINSTANCE="yes"
                  MAXIMIZEBUTTON="yes"
            >
      </head>
      <script language="VBScript">
      
      	<<<<<QUI METTI IL CODICE VBScript>>>>>
      
Sub Window_OnLoad
	<<<<<QUI METTI IL CODICE DA ESEGUIRE ALLA PARTENZA>>>>>
End Sub

Sub NomeSub( )
      
      	<<<<<QUI METTI IL CODICE della subroutineVBScript>>>>>
      
End Sub
</script>
   
      <body>
            <div id="tabs">
                  <ul>
                  <li><a href="#fragment-1">Username</a></li>
                  <li><a href="#fragment-2">User Definition</a></li>
                  <li><a href="#fragment-3">Group Domain</a></li>
                  <li><a href="#fragment-4">Create Ticket</a></li>
                  <li><a href="#fragment-5">Provvisioning</a></li>
                  <li><a href="#fragment-6">Test Linux</a></li>
                  </ul>
                  <div id="fragment-1"><br><br>Questa è una prova di GUI </div>
                  <div id="fragment-2">Prova2</div>
                  <div id="fragment-3">Prova3</div>
                  <div id="fragment-4">Prova</div>
                  <div id="fragment-5">Provvisioning</div>
                  <div id="fragment-6">TestLinux</div>
            </div>
            <script>
                  $("#tabs").tabs();
            </script>
      </body>
</html>

L’applicazione può eseguire un solo script o varie sub-routine.
Per creare una prima applicazione, basta copiare ed incollare questo src su un notepad e salvare il file come .HTA

Per chi è alle prime armi, esiste un fantastico strumento (sviluppato anch’esso in VBS e HTA) che riunisce la gran parte delle operazioni di input ed output, HTA HELPOMATIC degli Scripting Guy.

Vi posterò presto il link per scaricarlo, dato che sono anni che non si trova.

Se vi è piaciuto l’articolo, fatemelo sapere con un commento =)

Vostro Tommy – tommy [@] madlabs.org

Che figata! caricare contenuti sul Kindle è facile come mandare una e-Mail

Ciao Sbabbari, Ho avuto il piacere di avere tra le mani un Amazon Kindle nuovo di pacca, che un amico mi ha chiesto di comprargli approfittando del prime-day. Premetto che possiedo da molto tempo un lettore simile della Sony, che è lontano anni luce da quello del colosso guidato da Jeff Bezos.

Con il mio fedelissimo Sony sono abituato a spostare tutto tramite Esplora Risorse del pc o su di una SD, quindi la prima cosa che ho fatto OoB è stato collegare il dispositivo al mio computer, ma tranne che per il led di carica, il collegamento non ha sortito effetto alcuno.

Quindi, come caricare file differenti da quelli acquistati sullo store della casa madre? Semplicissimo, basta mandare una mail al dispositivo!

Accedendo al sito www.amazon.it/myk è possibile attivare il servizio Documenti Personali, che permette di caricare tramite una semplice mail contenuti testuali quali:

  • Mobi (Formato per eBook)
  • Microsoft Word (.doc, .docx)
  • Rich Text Format (.rtf)
  • HTML (.htm, .html)
  • Documenti di testo (.txt)
  • Documenti archiviati (zip , x-zip) e documenti archiviati compressi
  • Immagini nei formati: JPEG (.jpg), GIF (.gif), Bitmap (.bmp) e PNG (.png).
  • documenti in formato Adobe PDF (.pdf)

La funzione è abilitabile alla voce Preferenze

Abilitando il servizio, Amazon creerà una casella di posta di servizio @kindle.com. Questa non sarà una vera e propria mailbox, ma solamente una casella postale tecnica di sola ricezione. Per creare un indirizzo univoco, viene preso l’alias della mailbox con cui si è registrati su Amazon, al netto del dominio, con l’aggiunta di una serie di lettere casuali per garantirne l’univocità. Consiglio di modificarla con una cosa più semplice ed intuitiva (Nel nostro caso è bastato rimuovere i caratteri supplementari per avere equipollenza tra l’alias della mailbox e quello dell’indirizzo Kindle.

Per evitare spam ed abusi, solo le caselle autorizzate in White-list hanno il consenso per il caricamento di contenuti sul dispositivo.

Da qui premendo il link evidenziato in giallo è possibile inserire un nuovo indirizzo mittente autorizzato in White List

Quindi, per inviare un proprio eBook, un PDF o un qualsiasi altro tipo di documento, basta allegarlo ad una mail indirizzata alla casella @kindle.com.
Possono essere inviati fino a 25 file per messaggio e salvo errori, i file verranno caricati sul cloud di Amazon e scaricati sul dispositivo.

Elenco dei file personali – menù Contenuti -> Documenti

Semplicissimo no?

Se si desidera invece organizzare la propria libreria digitale ed avere uno strumento tout cour per la gestione dei file e la trasmissione a Kindle potete provare anche ad usare Calibre (Open Source: https://calibre-ebook.com/download)

Tommy
Tommy[at]madlabs.org

Risultato di una Query DB2 in uno script QSH su AS400

Spero che questo sia solo il primo di un lunghissimo elenco di tips ed articoli tecnici su questo sito.

Se volessimo usare il risultato di una qualsiasi query in una variabile di uno script SH?

Esempio: in una tabella DB2 ho un elenco di parametri definiti per utente:

Tabella SEDECENTRALE.UFFICIO

|Utente |Ufficio | Mailbox
—————————————————
|andrea |01 | andrea@ufficio.com
|marco |02 | marco@ufficio.com

i record nella colonna “Utente” corrispondono agli username della macchina.
L’utente “andrea” se lanciasse da QSH lo script qui sotto riportato, riceverebbe come output la mailbox contenuta nella tabella sopra riportata:

!/usr/bin/qsh
VAR=$(db2 “select Mailbox from SEDECENTRALE.UFFICIO where Utente = $LOGNAME ‘”|sed -e ‘1,3d’|tail -r|tail +4|tail -r| xargs |cut -d ‘;’ -f 1)
echo $VAR

NOTA BENE: QSHELL è Posix Compliant e molti dei comandi e delle variabili d’ambiente sono ereditate da UNIX. $LOGNAME è una variabile d’ambiente che restituisce l’utenza connessa al sistema.


Eravamo quattro amici al bar…

Quattro amici al bar, davvero azzeccato. Una folle idea partorita un pomeriggio d’estate da tre folli nel parcheggio di Via dei Capasso (poi diventati quattro), con una Coronita e lime in mano, nell’altra una sigaretta. Gli scooter come sedie e una strada come punto d’incontro.

Un non-luogo è stato teatro di un sogno, di un qualcosa che ci sembrava un impresa titanica, che da lì a poco avrebbe portato a non poche soddisfazioni.

Sono passati circa 16 anni da quel momento.
MADLABS.org è stato registrato precisamente il 16/10/2004.

Volevamo fin dall’inizio il .org – volevamo fin da subito mettere le cose in chiaro: doveva essere una iniziativa senza scopo di lucro per la diffusione del sapere. Un consesso di liberi pensatori che professavano il mantra “il sapere di tutti a tutti”.

Eravamo una comitiva di giovani e pieni di belle speranze. Spensierati e con tanta voglia di conoscere il mondo. Ci sono volute settimane per mettere in piedi qualcosa che funzionasse: Un VPS preso non-so-come da un provider internazionale (con relative prime manie di grandezza) il primo set di articoli, contenuti, pagine ecc ecc.

Purtroppo si cresce, si devono fare i conti con la vita, con il lavoro, la famiglia. Dopo la scomparsa di Luca, uno dei fondatori, il sito è stato piano piano abbandonato, poi ho deciso di chiuderlo. Ho disdetto tutto, hosting, housing, chiuso DB e Mailserver. Tutto eccetto i domini. Non volevo che qualcuno se ne impadronisse, l’ho custodito gelosamente per anni come un vessillo, una bandiera. non volevo che qualcuno sfoggiasse la nostra bandiera.

Ora risorge dalle ceneri come una fenice questo piccolo blog. Spero che abbia successo come la prima versione di MaDlabs.org. Questa rinascita la dedico a Luca “Debug”, Valerio “Junio”, Davide “AcCiO”, Mirko “DarkFuneral”, Stefano “Step”, Claudia e Tata, ed a tutti coloro che hanno creduto nel progetto del MADLABS originario.

Tommy