<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">

<channel>
	<title>Flaz Dot Biz</title>
	<link>http://flaz.biz/A55CEC/blog.nsf</link>
	<description>If anything can go wrong, it will</description>
	<pubDate>Sat, 25 May 2013 16:33:45 GMT</pubDate>
	<generator>NotePress</generator>
	<language>en</language>
	

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/flazbiz" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="flazbiz" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
<title>Zopo ZP810</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2013-05-zopo-zp810?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2013-05-zopo-zp810?open=feed#comments</comments>
<pubDate>Sat, 25 May 2013 17:03:22 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Mobile]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2013-05-zopo-zp810?open=feed</guid>

<description><![CDATA[ Circa un mese fa ho dovuto sostituire il BlackBerry Storm 2 che ormai da quasi cinque anni mi accompagnava quotidianamente. La scelta del sistema operativo &#232; stata facile, anche perch&#233;, andando per esclusione, l’unico per me appetibile era Android. Al contrario la scelta del dispositivo &#232; stata piuttosto dura.
Dopo un po’ di ricerche ho preso coraggio e mi sono deciso a prendere un cinafonino, convinto anche dal fatto che non solo l’avrei acquistato in Italia, e quindi con garanzia italiana, ma avrei potuto provarlo e vederlo dal vivo dal rivenditore di Udine a poche decine di km ]]></description>

<content:encoded><![CDATA[ Circa un mese fa ho dovuto sostituire il BlackBerry Storm 2 che ormai da quasi cinque anni mi accompagnava quotidianamente. La scelta del sistema operativo &#232; stata facile, anche perch&#233;, andando per esclusione, l’unico per me appetibile era Android. Al contrario la scelta del dispositivo &#232; stata piuttosto dura.
<br />Dopo un po’ di ricerche ho preso coraggio e mi sono deciso a prendere un <i>cinafonino</i>, convinto anche dal fatto che non solo l’avrei acquistato in Italia, e quindi con garanzia italiana, ma avrei potuto provarlo e vederlo dal vivo dal rivenditore di Udine a poche decine di km da casa mia.
<br />
<br />Non mi dilungo sulle caratteristiche tecniche che sono sicuramente pi&#249; complete e dettagliate nel sito del produttore. A distanza di un mese circa dall’utilizzo volevo scrivere alcune impressioni che ho avuto in questo primo periodo.
<br />
<br />La <b>batteria</b> &#232; in genere un tasto delicato degli smartphone pi&#249; recenti. Con lo ZP810 invece devo spendere parole positive: la durata &#232; di due giorni con uso, per me, normale. Se intensivo in una giornata arrivo a consumarne i 2/3. Mi aspettavo molto peggio. La seconda batteria &#232; inclusa nel prezzo, quindi &#232; davvero impossibile non arrivare a fine giornata con questo smartphone.
<br />
<br />Le <b>prestazioni</b> sono eccellenti. Il quad-core garantisce un’ottima velocit&#224; e nessun tipo lag. La temperatura del dispositivo non &#232; per nulla elevata e non subisce variazioni percettibili a seconda dell’uso pi&#249; o meno intensivo.
<br />
<br />L’uso della <b>tastiera</b> &#232; molto agevole per via delle generose dimensioni dello <b>schermo</b>. Gi&#224; in portrait si riesce a scrivere molto velocemente ed errori sono veramente difficili da compiere. Certo le <b>dimensioni</b> non lo rendono facilmente trasportabile, ma per me questo non &#232; un problema poich&#233; sono solito tenere il telefono nel giubbotto o nel borsello. Ci&#242; che non avevo considerato &#232; che con uno schermo di queste dimensioni &#232; impossibile raggiungere ogni punto dello schermo col pollice della stessa mano che afferra il terminale. In parole povere il suo utilizzo richiede quasi sempre due mani.
<br />
<br />La sensazione al tatto &#232; di solidit&#224;. Il retro &#232; liscio e una <b>cover</b> &#232; quasi d’obbligo per evitare che scivoli. La <b>pellicola</b> protettiva l’ho usata per un paio di settimane, per poi toglierla poich&#233; per i miei gusti penalizza troppo la sensibilit&#224;.
<br />
<br />Il <b>GPS</b> ha qualcosa che non va. Usando Runtastic, Endomondo o Prezzi Benzina le distanze calcolate sono errate, sebbene la posizione sia rilevata correttamente. Verrebbe da pensare a un problema software, anche se la versione di Android non &#232; stata personalizzata da Zopo. Non sono l’unico a rilevare questo problema sullo ZP810 per cui confido in un aggiornamento.
<br />
<br />Faccio uso del <b>bluetooth</b> esclusivamente per collegare il telefono al vivavoce della mia auto. Seppur non incluso tra i telefoni supportati, funzionano molto bene sia  vivavoce che rubrica.
<br />
<br />All’avvio di una telefonata l’<b>accelerometro</b> dovrebbe disattivare lo schermo quando lo smartphone &#232; portato all’orecchio. Cosa che non avviene sempre, suppongo per ragioni di scarsa sensibilit&#224;. Ci&#242; comporta che col viso si vada a <i>tappare</i> determinate zone dello schermo con le conseguenze del caso. Ormai ho preso l’abitudine di disattivare lo schermo con il tasto posto a fianco.
<br />
<br />L’audio in telefonata &#232; buono. Non ottimo, n&#233; scarso. Il <b>vivavoce</b> ha un volume appena sufficiente mentre gli <b>auricolari</b> forniti sono di qualit&#224; piuttosto bassa. Si riesce ugualmente ad ascoltare la musica in modo decente, ma non senza mettere mano all'equalizzatore.
<br />
<br />Della <b>fotocamera</b> non ne posso certo parlare bene. Il fuoco &#232; un disastro, finch&#233; si fotografano oggetti a circa mezzo metro di distanza la foto &#232; accettabile. Pi&#249; ci si allontana pi&#249; la foto sar&#224; sfuocata, in modo non omogeneo oltretutto (la parte destra della foto &#232; migliore - ovvero pi&#249; a fuoco - di quella sinistra).
<br />
<br />Nel complesso sono soddisfatto. Non mi aspettavo la perfezione, del resto costa 1/3 rispetto a un Samsung di pari caratteristiche. La fotocamera &#232;, secondo me, il vero problema. Ammesso che le distanze calcolate sulla base delle coordinate GPS saranno risolte in futuro. ]]></content:encoded>

</item>

<item>
<title>iNotes dietro reverse proxy HTTPS</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2013-04-inotes-dietro-reverse-proxy-https?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2013-04-inotes-dietro-reverse-proxy-https?open=feed#comments</comments>
<pubDate>Fri, 26 Apr 2013 09:44:25 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Lotus]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2013-04-inotes-dietro-reverse-proxy-https?open=feed</guid>

<description><![CDATA[ Ho acquistato un certificato con validit&#224; triennale per 5 domini su GoDaddy cos&#236; da mettere dietro reverse proxy ogni servizio HTTP in azienda.
L'esigenza &#232; nata principalmente dal fatto che dopo aver mandato in pensione il BlackBerry Storm II, usare Lotus Traveler senza passare da SSL proprio non mi andava gi&#249;.
Il certificato &#232; installato su un reverse proxy in Apache 2.0 su Debian. ]]></description>

<content:encoded><![CDATA[ Ho acquistato un certificato con validit&#224; triennale per 5 domini su <a href="http://www.godaddy.com/ssl/ssl-certificates.aspx">GoDaddy</a> cos&#236; da mettere dietro reverse proxy ogni servizio HTTP in azienda.
<br />L'esigenza &#232; nata principalmente dal fatto che dopo aver mandato in pensione il BlackBerry Storm II, usare Lotus Traveler senza passare da SSL proprio non mi andava gi&#249;.
<br />
<br />Il certificato &#232; installato su un <a href="http://flaz.biz/A55CEC/blog.nsf/post/2009-04-la-risposta-e-proxy">reverse proxy</a> in Apache 2.0 su Debian.
<br />Il client si collega al reverse proxy in HTTPS, e il reverse proxy si collega al server web interno in HTTP.
<br />Quindi ciascun server web interno di fatto dialoga con il proprio interlocutore (reverse proxy) in HTTP.
<br />
<br />Ho notato immediatamente un problema nella webmail iNotes la cui redirezione alla posta che avviene a seguito del login fallisce in quanto redirige verso l'indirizzo corretto, ma con protocollo HTTP anzich&#233; HTTPS.
<br />
<br />La soluzione &#232; nell'iNotes Redirect (iwaredir.nsf): da Configurazione, Impostazioni server, la voce <b>&quot;Si vuole omettere il protocollo dall'URL di redirezione?&quot;</b> dovr&#224; essere <b>S&#236;</b>.
<br />
<br />Un altro problema sono gli endpoint nei webservice delle applicazioni Domino, che anche qui riportano l'indirizzo su protocollo HTTP.
<br />Ma ne riparler&#242; quando ci avr&#242; dedicato del tempo e trovato la soluzione. E magari dedicher&#242; anche un post per parlare del pensionamento del BlackBerry e del suo sostituto! ]]></content:encoded>

</item>

<item>
<title>Lotus Domino 8.5.3 FP3</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2013-03-lotus-domino-8-5-3-fp3?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2013-03-lotus-domino-8-5-3-fp3?open=feed#comments</comments>
<pubDate>Wed, 13 Mar 2013 21:59:09 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[GNU/Linux]]></category>

<category><![CDATA[Lotus]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2013-03-lotus-domino-8-5-3-fp3?open=feed</guid>

<description><![CDATA[ Ieri ho installato il FP3 su un server Lotus Domino su Linux CentOS dalla versione 8.5.3 FP2.
L'installazione ha ripristinato il java.policy allo stato originale e eliminato tutte le librerie Java esterne.
Ci sta l'aggiornamento di release che sovrascriva il java.policy. E lo posso tollerare anche da un Fix Pack, sebbene non mi fosse mai capitato prima.
Ma che elimini i miei file JAR dalla /lib/ext non mi va proprio gi&#249;. ]]></description>

<content:encoded><![CDATA[ Ieri ho installato il FP3 su un server Lotus Domino su Linux CentOS dalla versione 8.5.3 FP2.
<br />L'installazione ha ripristinato il java.policy allo stato originale e eliminato tutte le librerie Java esterne.
<br />
<br />Ci sta l'aggiornamento di release che sovrascriva il java.policy. E lo posso tollerare anche da un Fix Pack, sebbene non mi fosse mai capitato prima.
<br />Ma che <b>elimini</b> i miei file JAR dalla <code>/lib/ext</code> non mi va proprio gi&#249;. ]]></content:encoded>

</item>

<item>
<title>FreeNAS</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2013-02-freenas?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2013-02-freenas?open=feed#comments</comments>
<pubDate>Sun, 24 Feb 2013 12:08:46 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[GNU/Linux]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2013-02-freenas?open=feed</guid>

<description><![CDATA[ Dopo la traidgedia dello scorso anno, il server casalingo &#232; rimasto praticamente sempre fermo. Principalmente per il poco tempo da dedicarci ma anche perch&#233; di fatto ne sentivo molto poco la mancanza. Lo SMART mi segnalava problemi su uno dei quattro dischi e non ho mai avuto voglia di prendere in mano la situazione, approfondire e risolvere.
Lo scorso weekend ho finalmente deciso di dedicarmi al problema, con l'obiettivo principale di semplificare tutto il sistema: niente pi&#249; Debian, Samba, VMware, macchine virtuali, ecc. ]]></description>

<content:encoded><![CDATA[ Dopo la <a href="http://flaz.biz/A55CEC/blog.nsf/post/2012-04-traidgedia">traidgedia</a> dello scorso anno, il server casalingo &#232; rimasto praticamente sempre fermo. Principalmente per il poco tempo da dedicarci ma anche perch&#233; di fatto ne sentivo molto poco la mancanza. Lo SMART mi segnalava problemi su uno dei quattro dischi e non ho mai avuto voglia di prendere in mano la situazione, approfondire e risolvere.
<br />
<br />Lo scorso weekend ho finalmente deciso di dedicarmi al problema, con l'obiettivo principale di semplificare tutto il sistema: niente pi&#249; Debian, Samba, VMware, macchine virtuali, ecc. troppa confusione. Negli ultimi periodi sfruttavo esclusivamente le condivisioni, tanto che ero quasi deciso ad orientarmi su un semplice NAS di rete. Dal momento che per&#242; l'hardware del mio server non &#232; poi cos&#236; datato, anzi, per essere mandato in pensione ho deciso di sfruttarlo ancora per un po' con <b><a href="http://www.freenas.org">FreeNAS</a></b>.
<br />
<br />Ho tolto un disco, quello indicato dallo SMART come danneggiato, optando quindi per uno stra-sicuro RAID 1 con un disco di spare. Spazio utile 1 TB, me lo far&#242; bastare.
<br />Il sistema operativo risiede su una chiavetta USB da 2 GB.
<br />
<br />Trovo FreeNAS davvero semplice da usare. Tempo addietro avevo fatto alcune installazioni di OpenFiler e, se non sono cambiate le cose, in quanto a semplicit&#224; d'uso FreeNAS mi sembra una spanna avanti.
<br />
<br />Noto subito una gran lentezza sulle condivisioni Samba: soli 50 file in una cartella vengono caricati <i>a blocchi</i>. La soluzione &#232; fortunatamente immediata, trattasi di abilitare il <b>Large RW support</b>, da Services &gt; CIFS &gt; Settings.
<br />
<br />Il sistema assolve generalmente bene ai suoi compiti.
<br />
<br />Documentandomi scopro che il televisore Samsung SMART acquistato da pochi giorni ha la possibilit&#224; di riprodurre via rete wireless video residenti su condivisioni di rete.
<br />FreeNAS non viene rilevato, cos&#236; seguendo l'ottima <a href="http://doc.freenas.org/index.php/Plugins#Installing_the_Plugins_Jail">documentazione</a> installo e configuro prima il <b>Plugins Jail</b>, quindi <b>MiniDLNA</b>.
<br />Seguo alla lettera le istruzioni e la TV rileva istantaneamente il NAS ed i file condivisi. Ora posso riprodurre tranquillamente video, musica e foto senza bisogno di collegare la TV al PC o passare per chiavette USB da collegare alla TV.
<br />
<br />Davvero soddisfatto, sia di FreeNAS che della TV Samsung la cui definizione grazie alla tecnologia a LED &#232; senza dubbio superlativa. ]]></content:encoded>

</item>

<item>
<title>Uptime</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2013-01-uptime?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2013-01-uptime?open=feed#comments</comments>
<pubDate>Tue, 22 Jan 2013 08:40:39 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[GNU/Linux]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2013-01-uptime?open=feed</guid>

<description><![CDATA[ Prima di spegnere i server a Dicembre causa trasloco, ho voluto salvare questo screenshot per i posteri:
 ]]></description>

<content:encoded><![CDATA[ Prima di spegnere i server a Dicembre causa trasloco, ho voluto salvare questo screenshot per i posteri:
<br />
<br /><a href="http://flaz.biz/A55CEC/blog.nsf/0/C3D4B52D0EFEA1B3C1257AFB002FB341/$FILE/uptime.png" style="border:0"><img src="http://flaz.biz/A55CEC/blog.nsf/0/C3D4B52D0EFEA1B3C1257AFB002FB341/$FILE/thumb.jpg" alt="Uptime" /></a> ]]></content:encoded>

</item>

<item>
<title>Convertire DOC(X) in PDF con le API di Word</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2012-05-convertire-doc-x-in-pdf-con-le-api-di-word?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2012-05-convertire-doc-x-in-pdf-con-le-api-di-word?open=feed#comments</comments>
<pubDate>Fri, 11 May 2012 13:39:59 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Lotus]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2012-05-convertire-doc-x-in-pdf-con-le-api-di-word?open=feed</guid>

<description><![CDATA[ Dalla versione 2007 di Office &#232; possibile esportare un documento Word nel formato PDF senza bisogno di stampanti PDF esterne.
Ci&#242; &#232; riproducibile anche attraverso le API di Office scrivendo poche righe di codice in LotusScript.
Il codice che segue &#232; il sorgente di un pulsante nella barra delle operazioni che, a partire dal file DOC (o DOCX) presente nel campo Allegato, lo converte nel formato PDF e lo salva in un percorso richiesto all'utente:
Const wdExportFormatPDF = 17
Const wdExportOptimizeForPrint = 0
Sub Click(Source As Button)
	
	Dim ws As New notesuiworkspace
	Dim ]]></description>

<content:encoded><![CDATA[ Dalla versione 2007 di Office &#232; possibile esportare un documento Word nel formato PDF senza bisogno di stampanti PDF esterne.
<br />Ci&#242; &#232; riproducibile anche attraverso le API di Office scrivendo poche righe di codice in LotusScript.
<br />
<br />Il codice che segue &#232; il sorgente di un pulsante nella barra delle operazioni che, a partire dal file DOC (o DOCX) presente nel campo <code>Allegato</code>, lo converte nel formato PDF e lo salva in un percorso richiesto all'utente:

<pre name="code" class="vb">Const wdExportFormatPDF = 17
Const wdExportOptimizeForPrint = 0

Sub Click(Source As Button)
	
	Dim ws As New notesuiworkspace
	Dim doc As notesdocument
	Dim rtitem As notesrichtextitem
	Dim eo As notesembeddedobject
	Dim docFilePath As String, pdfFilePath As Variant
	Dim wordObject As Variant, wordDocument As Variant
	
	Set doc = ws.currentdocument.document
	Set rtitem = doc.getfirstitem(&quot;Allegato&quot;)
	Set eo = rtitem.EmbeddedObjects(0)

	pdfFilePath = ws.SaveFileDialog(False, &quot;Salva PDF&quot;, &quot;*.PDF&quot;, Environ(&quot;USERPROFILE&quot;) + &quot;\Desktop&quot;, StrLeftBack(eo.Name, &quot;.&quot;) + &quot;.PDF&quot;)
	If IsEmpty(pdfFilePath) Then Exit Sub
	
	docFilePath = Environ(&quot;TEMP&quot;) + &quot;\&quot; + eo.Name
	Call eo.ExtractFile(docFilePath)
	
	Set wordObject = CreateObject(&quot;Word.Application&quot;)
	wordObject.Visible = False
	Set wordDocument = wordObject.Documents.Open(docFilePath)
	
	Call wordDocument.ExportAsFixedFormat(pdfFilePath(0), wdExportFormatPDF, False, wdExportOptimizeForPrint)
	
	Call wordDocument.Close(False)
	Call wordObject.Quit()
	
End Sub</pre>

In questo modo il PDF viene semplicemente salvato. In alternativa &#232; possibile aprire il PDF subito dopo la conversione sostituendo la riga <code>ExportAsFixedFormat</code> con:

<pre name="code" class="vb">Call wordDocument.ExportAsFixedFormat(pdfFilePath(0), wdExportFormatPDF, True, wdExportOptimizeForPrint)</pre> ]]></content:encoded>

</item>

<item>
<title>Leggere più campi omonimi contenuti nello stesso documento</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2012-05-leggere-piu-campi-omonimi-contenuti-nello-stesso-documento?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2012-05-leggere-piu-campi-omonimi-contenuti-nello-stesso-documento?open=feed#comments</comments>
<pubDate>Thu, 10 May 2012 16:34:58 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Lotus]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2012-05-leggere-piu-campi-omonimi-contenuti-nello-stesso-documento?open=feed</guid>

<description><![CDATA[ A tal riguardo la guida di Domino Designer inerente il metodo GetFirstItem della NotesDocument riporta:
A document may contain more than one item of the same name. To access other than the first item, use the Items property of NotesDocument. This code gets all items named &quot;Item33&quot;:
Forall item In doc.Items
	If item.Name = &quot;Item33&quot; Then
		' Process one item
	End If
End Forall
Il sistema suggerito trova tanti NotesItem quanti sono realmente i campi con lo stesso nome, ma il valore di ciascuno di questi &#232; sempre quello del primo campo trovato. ]]></description>

<content:encoded><![CDATA[ A tal riguardo la guida di Domino Designer inerente il metodo <code>GetFirstItem</code> della <code>NotesDocument</code> riporta:

<blockquote>A document may contain more than one item of the same name. To access other than the first item, use the Items property of NotesDocument. This code gets all items named &quot;Item33&quot;:

<pre name="code" class="vb">Forall item In doc.Items
	If item.Name = &quot;Item33&quot; Then
		' Process one item
	End If
End Forall</pre></blockquote>

Il sistema suggerito trova tanti <code>NotesItem</code> quanti sono realmente i campi con lo stesso nome, ma il valore di ciascuno di questi &#232; sempre quello del primo campo trovato.
<br />
<br />Nonostante IBM stessa sconsigli l'utilizzo di nomi di campi uguali all'interno dello stesso documento, gli header doppi nelle e-mail non vengono <i>itemizzati</i> in un unico campo con valori multipli, bens&#236; in pi&#249; campi con lo stesso nome e valore singolo.
<br />
<br />Io ho l'esigenza di identificare la provenienza di un'e-mail in base all'indirizzo IP sorgente, e anche nella migliore delle ipotesi in cui i due server SMTP comunicano direttamente il numero di <i>hop</i> &#232; pari a due, e altrettanti saranno gli header Received.
<br />Il modo corretto per ottenere ciascun campo distinto consiste nel leggere il primo, eliminarlo, passare al successivo, eliminarlo, e cos&#236; via:

<pre name="code" class="vb">Dim received As Variant

Set item = memo.GetFirstItem(&quot;Received&quot;)
Do Until item Is Nothing

	If IsNull(received) Then
		received = item.values
	Else
		received = ArrayAppend(received, item.values)
	End If
	
	Call item.Remove()
	Set item = memo.GetFirstItem(&quot;Received&quot;)
Loop</pre>

Naturalmente se il documento dovesse essere successivamente salvato si vanno a perdere i campi eliminati. Alternativamente si pu&#242; lavorare su una copia del documento interamente in memoria:

<pre name="code" class="vb">Dim received As Variant
Dim tmpdoc As NotesDocument

Set tmpdoc = memo.ParentDatabase.CreateDocument()
Call memo.CopyAllItems(tmpdoc, True)

Set item = tmpdoc.GetFirstItem(&quot;Received&quot;)
Do Until item Is Nothing

	If IsNull(received) Then
		received = item.values
	Else
		received = ArrayAppend(received, item.values)
	End If
	
	Call item.Remove()
	Set item = tmpdoc.GetFirstItem(&quot;Received&quot;)
Loop

Delete tmpdoc</pre>

Dal momento che il campo <code>Body</code> non &#232; per nulla necessario averlo nel <code>tmpdoc</code>, creandolo precedentemente senza alcun valore al suo interno ed evitando il <code>replace</code> della <code>CopyAllItems</code> si evita di allocare memoria inutilmente (se poi ci sono anche allegati la differenza in termini di memoria allocata e tempo d'attesa non &#232; per nulla irrilevante):

<pre name="code" class="vb">Set tmpdoc = memo.ParentDatabase.CreateDocument()
Call tmp.ReplaceItemValue(&quot;Body&quot;, &quot;&quot;)
Call memo.CopyAllItems(tmpdoc, False)</pre> ]]></content:encoded>

</item>

<item>
<title>WSDL server in PHP con NuSOAP e client Lotus Domino</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2012-05-wsdl-server-in-php-con-nusoap-e-client-lotus-domino?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2012-05-wsdl-server-in-php-con-nusoap-e-client-lotus-domino?open=feed#comments</comments>
<pubDate>Mon, 07 May 2012 18:51:12 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Lotus]]></category>

<category><![CDATA[PHP]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2012-05-wsdl-server-in-php-con-nusoap-e-client-lotus-domino?open=feed</guid>

<description><![CDATA[ La scorsa settimana un Cliente che seguo ha deciso di cambiare hosting provider, senza curarsi di verificare se il database MySQL fornito consentisse di accettare connessioni provenienti dall'esterno, cosa che abbiamo scoperto poi non fare. Visto il periodo, e soprattutto considerato il risparmio dal vecchio al nuovo provider, non posso neanche biasimarlo.
Quindi, pur vanificando il risparmio dei primi mesi, occorre trovare una soluzione alternativa alla query diretta sul database presso il provider. ]]></description>

<content:encoded><![CDATA[ La scorsa settimana un Cliente che seguo ha deciso di cambiare hosting provider, senza curarsi di verificare se il database MySQL fornito consentisse di accettare connessioni provenienti dall'esterno, cosa che abbiamo scoperto poi non fare. Visto il periodo, e soprattutto considerato il risparmio dal vecchio al nuovo provider, non posso neanche biasimarlo.
<br />
<br />Quindi, pur vanificando il risparmio dei primi mesi, occorre trovare una soluzione alternativa alla query diretta sul database presso il provider. La risposta &#232; ovvia: <b>webservice</b>!
<br />
<br />Il sito guarda caso &#232; fatto in PHP, dove ho gi&#224; avuto modo di <i>consumare</i> un webservice in svariate occasioni, ma mai di sviluppare un <b>WSDL Provider</b> affinch&#233; possa essere <i>consumato</i> da un agente Domino.
<br />
<br />Una mezz'ora di ricerche mi porta a scegliere <a href="http://sourceforge.net/projects/nusoap/" target="_blank">NuSOAP</a> come toolkit per sviluppare il server webservice. All'interno dell'archivio scaricabile liberamente la cartella <code>lib</code> contiene tutto il necessario per creare un webservice.
<br />
<br />Io sono solito sviluppare le risposte dei webservice come segue (supponendo che il webservice si chiami <code>Cliente</code>):

<ol>
<li>La funzione richiamata dal <i>consumer</i> restituisce un oggetto <code>ClienteResponse</code>;</li>
<li>La <code>ClienteResponse</code> contiene una variabile <code>errore</code> (<code>xsd:string</code>) e una variabile di tipo <code>ElencoClienti</code>;</li>
<li>La <code>ElencoClienti</code> non &#232; altro il contenitore di uno o pi&#249; elementi di tipo <code>Cliente</code>;</li>
<li>L'oggetto <code>Cliente</code> contiene le varie propriet&#224; che descrivono il dato (ragione sociale, partita iva, telefono, ecc.).</li>
</ol>

Il caso di cui sopra &#232; il mio modus operandi che adotto quando ho una quantit&#224; non definita di informazioni da restituire. Nel caso il numero di elementi (Clienti in questo caso) fosse definito si pu&#242; saltare un livello.
<br />
<br />Ad ogni modo, in LotusScript sviluppare una struttura di questo genere non &#232; altro che una matrioska di classi. In NuSOAP, anzi in PHP in generale, vengono in aiuto gli array associativi, con i loro vantaggi e svantaggi. Purtroppo NuSOAP pecca un po' in documentazione e sul fatto di non essere del tutto trasparente rispetto al wsdl che dovrebbe rappresentare la logica che lo descrive: le singole propriet&#224; (o campi) devono essere descritte direttamente in linguaggio XSD, gli array non sono molto intuitivi da dichiarare. Insomma &#232; un poco <i>grezzo</i>, ma una volta compreso come muoversi il risultato &#232; garantito.
<br />
<br />Tutto parte dalla dichiarazione del server:

<pre name="code" class="php">$server = new nusoap_server();
$server-&gt;configureWSDL('ClientiWSDL', 'urn:ClientiWSDL');</pre>

L'oggetto <code>ClientiResponse</code> deve essere dichiarato attraverso il metodo <code>addComplexType</code>:

<pre name="code" class="php">$server-&gt;wsdl-&gt;addComplexType(
	'ClientiResponse',
	'complexType',
	'struct',
	'sequence',
	'',
	array(
		'Errore' =&gt; array('name' =&gt; 'Errore', 'type' =&gt; 'xsd:string'),
		'Clienti' =&gt; array('name' =&gt; 'Clienti', 'type' =&gt; 'tns:ClienteArray')
	)
);</pre>

Apro una parentesi, &#232; cosa abbastanza comune definire le propriet&#224; come <code>nillable</code>, che in NuSOAP va fatto come segue:

<pre name="code" class="php">		'Errore' =&gt; array('name' =&gt; 'Errore', 'type' =&gt; 'xsd:string', 'nillable' =&gt; 'yes')</pre>

<code>ClientResponse</code> fa riferimento a <code>ClienteArray</code> (seconda elemento della risposta), che a sua volta &#232; un <i>ComplexType</i>:

<pre name="code" class="php">$server-&gt;wsdl-&gt;addComplexType(
	'ClienteArray',
	'complexType',
	'array',
	'',
	'SOAP-ENC:Array',
	array(),
	array(
		array('ref' =&gt; 'SOAP-ENC:arrayType', 'wsdl:arrayType' =&gt; 'tns:Cliente&#091;&#093;')
	),
	'tns:Cliente'
);</pre>

E dulcis in fundo la dichiarazione dell'oggetto <code>Cliente</code>, che &#232; l'informazione vera e propria:

<pre name="code" class="php">$server-&gt;wsdl-&gt;addComplexType(
	'Cliente',
	'complexType',
	'struct',
	'sequence',
	'',
	array(
		'ID' =&gt; array('name' =&gt; 'ID', 'type' =&gt; 'xsd:int'),
		'Ragsoc' =&gt; array('name' =&gt; 'Ragsoc', 'type' =&gt; 'xsd:string'),
		'Tel' =&gt; array('name' =&gt; 'Tel', 'type' =&gt; 'xsd:string'),
		'Tel2' =&gt; array('name' =&gt; 'Tel2', 'type' =&gt; 'xsd:string'),
		'Email' =&gt; array('name' =&gt; 'Email', 'type' =&gt; 'xsd:string'),
		'Fax' =&gt; array('name' =&gt; 'Fax', 'type' =&gt; 'xsd:string'),
		'CAP' =&gt; array('name' =&gt; 'CAP', 'type' =&gt; 'xsd:string'),
		'Indirizzo' =&gt; array('name' =&gt; 'Indirizzo', 'type' =&gt; 'xsd:string'),
		'Comune' =&gt; array('name' =&gt; 'Comune', 'type' =&gt; 'xsd:string'),
		'Provincia' =&gt; array('name' =&gt; 'Provincia', 'type' =&gt; 'xsd:string'),
		'Regione' =&gt; array('name' =&gt; 'Regione', 'type' =&gt; 'xsd:string')
	)
);</pre>

Una volta definiti i tipi di dati va registrato il metodo che verr&#224; richiamato per ottenere l'elenco del Clienti:

<pre name="code" class="php">$server-&gt;register(
	'ElencoClienti',
	array('password' =&gt; 'xsd:string'),
	array('return' =&gt; 'tns:ClientiResponse'),
	'urn:ElencoClienti',
	'urn:ElencoClienti#ElencoClienti',
	'rpc',
	'encoded'
);</pre>

Di norma evito di usare l'autenticazione HTTP, per cui il metodo viene richiamato specificando la password che consente di ottenere l'elenco richiesto.
<br />
<br />La <code>ElencoClienti</code> (primo parametro della funzione <code>register</code>) &#232; la funzione dovr&#224; essere normalmente definita in PHP, la quale ricever&#224; come parametro <code>$password</code> e dovr&#224; restituire la struttura dati definita come <code>ClientiResponse</code>, ovvero (semplificando):

<pre name="code" class="php">function ElencoClienti($password) {

	$res = array(
		'Errore' =&gt; '',
		'Clienti' =&gt; array()
	);

	$cliente = array(
		'ID' =&gt; 1,
		'Ragsoc' =&gt; 'Rossi SpA',
		'Tel' =&gt; '02123456789',
		'Tel2' =&gt; '',
		'Email' =&gt; 'rossi@rossi.com',
		'Fax' =&gt; '02123456789',
		'CAP' =&gt; '20121',
		'Indirizzo' =&gt; 'Via Roma, 1',
		'Comune' =&gt; 'Milano',
		'Provincia' =&gt; 'MI',
		'Regione' =&gt; 'Lombardia'
	);

	array_push($res&#091;'Clienti'&#093;, $cliente);

	// altri clienti...

	return $res;

}</pre>

In ultimo l'end point dovr&#224; passare alla variabile <code>$server</code> l'intero HTTP POST:

<pre name="code" class="php">$server-&gt;service( (isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '') );</pre>

<h3>Memoria e tempi di esecuzione</h3>

L'hosting provider presso cui &#232; stato installato il webservice ha, evidentemente, una configurazione di <code>php.ini</code> piuttosto limitativa per l'esecuzione degli script, sia in termini di memoria che di tempo di esecuzione, tuttavia risolvibile con un paio di righe:

<pre name="code" class="php">set_time_limit(600);
ini_set('memory_limit', -1);</pre>

<h3>Download</h3>

Per chi volesse prelevare il webservice d'esempio, che poi &#232; quello che ho costruito per fare i test, &#232; disponibile per il <a href="http://flaz.biz/A55CEC/blog.nsf/0/9B5A2298D4DCDBABC12579F80044B878/$FILE/wsdl.zip">download</a>.

<h3>WSDL Client</h3>

Come WSDL Client per eseguire prove e collaudi vari ho sempre usato WCFStorm Lite. Nulla di eccelso, ma faceva quanto mi era necessario.
<br />Usando NuSOAP sono per&#242; emersi un paio di problemi:

<ul>
<li>Il server di sviluppo che uso &#232; un LAMP su Debian, e la risposta a qualsiasi richiesta di esecuzione del webservice era un HTTP Code 417 (Expectations). Non ho risolto, n&#233; approfondito in verit&#224;, ma sono sicuro che l'<i>incomprensione</i> esiste solo tra WCFStorm Lite e NuSOAP.</li>
<li>Problemi di charset: WCFStorm Lite invia richieste solo in UTF-8, e NuSOAP risponde solo in ISO-8859-1. Il che a WCFStorm non piace, vanificando la sua utilit&#224; di client WSDL. Tra parentesi in NuSOAP non &#232; assolutamente possibile modificare il charset, se non manualmente nei sorgenti.</li>
</ul>

Quindi, ho deciso che era ora di rinnovarmi &#232; mi sono convertito a <a href="http://www.soapui.org/" target="_blank">soapUI</a>. Non una piuma, quasi 160 MB contro i 6 MB di WCFStorm Lite (che tra le altre cose neanche ha bisogno di installazione), ma c'&#232; da dire che &#232; sicuramente molto pi&#249; accurato e, se sfruttate tutte le sue caratteristiche, &#232; un buono strumento. Si scende pi&#249; <i>a basso livello</i> rispetto a WCFStorm Lite, nel senso che &#232; possibile vedere l'intera richiesta e relativa risposta, dagli header HTTP al documento XML inviato/ricevuto. Cosa decisamente utile a fini di debug.

<h3>Utilizzo in Lotus Domino Designer</h3>

Utilizzare il webservice appena creato dal Designer &#232; questione di pochi click:
<br />
<br /><img src="http://flaz.biz/A55CEC/blog.nsf/0/F1E6E298DE2CE4C3C12579F800444D79/$FILE/new-webservice-consumer-button.jpg" alt="New Webservice Consumer Button" />
<br />
<br /><img src="http://flaz.biz/A55CEC/blog.nsf/0/A234D68FF18F6F41C12579F800437FA9/$FILE/new-webservice-consumer-window.jpg" alt="New Webservice Consumer Window" />
<br />
<br />Il webservice che il Designer crea ha la stessa struttura <i>a matrioska</i> imposta in PHP:

<pre name="code" class="vb">%INCLUDE &quot;lsxsd.lss&quot;
Class Cliente_n8 As XSD_ANYTYPE
	
	Public ID As Long
	Public Ragsoc As String
	Public Tel As String
	Public Tel2 As String
	Public Email As String
	Public Fax As String
	Public CAP As String
	Public Indirizzo As String
	Public Comune As String
	Public Provincia As String
	Public Regione As String
	
	Sub NEW
	End Sub
	
End Class

Class ClientiResponse_n8 As XSD_ANYTYPE
	
	Public Errore As String
	Public Clienti() As Cliente_n8
	
	Sub NEW
	End Sub
	
End Class

Const n8 = &quot;urn:ClientiWSDL&quot;
Class ClientiWSDLPortType_n8 As PortTypeBase
	
	Sub NEW
		Call Service.Initialize (&quot;UrnClientiWSDLClientiWSDL&quot;, _
		&quot;ClientiWSDL.ClientiWSDLPort&quot;, &quot;http://172.20.3.106/wsdl/clienti.php&quot;, &quot;ClientiWSDLPortType_n8&quot;)
		
	End Sub
	
	Function ElencoClienti(password As String) As ClientiResponse_n8
		Set ElencoClienti = Service.Invoke(&quot;ElencoClienti&quot;, password)
	End Function
	
End Class</pre>

Due nomi vanno letti e ricordati: <code><b>ClientiWSDLPortType_n8</b></code> e <code><b>ClientiResponse_n8</b></code>, in quanto questi sono gli oggetti da utilizzare per chiamare il webservice e riceverne la risposta:

<pre name="code" class="vb">Option Public
Option Declare

Use &quot;clienti.wsdl&quot;

Const PASSWORD = &quot;c5ecf192a9b865cc7b4df8b46d2c5621&quot;

Sub Initialize
	Dim wsdl As New ClientiWSDLPortType_n8
	Dim res As ClientiResponse_n8
	Set res = wsdl.ElencoClienti(PASSWORD)
	ForAll cliente In res.Clienti()
		Print cliente.Ragsoc
	End ForAll
End Sub</pre>

La risposta (<code>res</code>) contiene la variabile atta ad ospitare l'eventuale errore, e l'elenco dei Clienti:
<br />
<br /><img src="http://flaz.biz/A55CEC/blog.nsf/0/E8190BE0052FCEAFC12579F800438966/$FILE/debug.jpg" alt="Debug" /> ]]></content:encoded>

</item>

<item>
<title>Esecuzione agenti da console su percorsi con spazi</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2012-05-esecuzione-agenti-da-console-su-percorsi-con-spazi?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2012-05-esecuzione-agenti-da-console-su-percorsi-con-spazi?open=feed#comments</comments>
<pubDate>Fri, 04 May 2012 16:04:48 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Lotus]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2012-05-esecuzione-agenti-da-console-su-percorsi-con-spazi?open=feed</guid>

<description><![CDATA[ La sintassi comune per eseguire on the fly agenti dalla console di Domino &#232;:
tell amgr run &quot;path\nomedb.nsf&quot; 'Nome Agente'
Mercoled&#236; sono stato da un Cliente la cui root degli applicativi &#232; &quot;DB Notes&quot;.
Il problema derivante da ci&#242; &#232; che l'esecuzione degli agenti da console con il comando che segue porta a un errore di Syntax error:
tell amgr run &quot;DB Notes\Produzione\ordini. ]]></description>

<content:encoded><![CDATA[ La sintassi comune per eseguire on the fly agenti dalla console di Domino &#232;:
<br />
<br /><code>tell amgr run &quot;path\nomedb.nsf&quot; 'Nome Agente'</code>
<br />
<br />Mercoled&#236; sono stato da un Cliente la cui root degli applicativi &#232; &quot;DB Notes&quot;.
<br />Il problema derivante da ci&#242; &#232; che l'esecuzione degli agenti da console con il comando che segue porta a un errore di <b>Syntax error</b>:
<br />
<br /><code>tell amgr run &quot;DB Notes\Produzione\ordini.nsf&quot; 'Importa Ordini'</code>
<br />
<br />La soluzione nella KB di IBM consiste nel rinominare il database (o la directory in questo caso).
<br />Ovviet&#224; a parte, nel Forum ho trovato un workaround tanto semplice quanto banale: usare l'apice singolo al posto del doppio apice agli estremi del percorso del database, ovvero:
<br />
<br /><code>tell amgr run 'DB Notes\Produzione\ordini.nsf' 'Importa Ordini'</code>
<br />
<br />Il problema &#232; noto e irrisolto da diverse release ormai, un po' come la <a href="http://flaz.biz/A55CEC/blog.nsf/post/2009-05-niente-language-pack-ita-per-la-domino-directory">Domino Directory in lingua italiana</a> che non fa funzionare l'internet site SMTP. ]]></content:encoded>

</item>

<item>
<title>Traidgedia</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2012-04-traidgedia?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2012-04-traidgedia?open=feed#comments</comments>
<pubDate>Thu, 19 Apr 2012 18:57:56 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[GNU/Linux]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2012-04-traidgedia?open=feed</guid>

<description><![CDATA[ La sera di un bel po' di settimane fa il server casalingo (lo stesso di un mio vecchio post) su cui gira un samba con tutti i miei dati, risponde, ma diversi file sono illeggibili. Controllo la VM su cui gira un Windows Server. Nessuna risposta.
Il syslog ha l'errore incubo di ogni sysadmin: il RAID5 &#232; passato a miglior vita. Poco pi&#249; di 1 TB di dati persi. Disperazione.
Passano diversi giorni, poi a ridosso di pasqua prendo coraggio e metto su una MEPIS Live per vedere se il disastro pu&#242; essere arginato. ]]></description>

<content:encoded><![CDATA[ La sera di un bel po' di settimane fa il server casalingo (lo stesso di un mio <a href="http://flaz.biz/A55CEC/blog.nsf/post/2010-11-ho-approfittato-del-ponte-per-cambiare-server">vecchio post</a>) su cui gira un samba con tutti i miei dati, risponde, ma diversi file sono illeggibili. Controllo la <abbr title="Virtual Machine">VM</abbr> su cui gira un Windows Server. Nessuna risposta.
<br />
<br />Il syslog ha l'errore incubo di ogni sysadmin: il RAID5 &#232; passato a miglior vita. Poco pi&#249; di 1 TB di dati persi. Disperazione.
<br />
<br />Passano diversi giorni, poi a ridosso di pasqua prendo coraggio e metto su una <a target="_blank" href="http://www.mepis.org/">MEPIS Live</a> per vedere se il disastro pu&#242; essere arginato.
<br />
<br />Provando ad assemblare l'array non sembra esserci molta speranza. Dopo poco scopro che con il <code>--force</code> l'esito &#232; positivo:
<br />
<br /><code>modprobe raid5
<br />mdadm --examine --scan
<br />mdadm --assemble -u &#091;mettere qua l'unid restituito dal comando precedente&#093; --force /dev/md0</code>
<br />
<br />L'avviso &#232; che &#232; stato escluso <code>/dev/sdd1</code>, che posso ugualmente aggiungere in seguito:
<br />
<br /><code>mdadm /dev/md0 --add /dev/sdd1</code>
<br />
<br />A questo punto parte la sincronizzazione, che su quattro Seagate Barracuda SATA impiega non poche ore. Nel frattempo monto l'unit&#224; e scopro con immensa soddisfazione che tutti i dati sono leggibili, inclusi quelli che mi avevano fatto accorgere del danno. Inizia il salvataggio su un paio di dischi di fortuna, la cui capacit&#224; per&#242; &#232; inferiore ai dati che devo salvare. Ma &#232; forse anche l'occasione per fare un po' di pulizia, che ogni tanto male non fa.
<br />
<br />La mattina seguente, terminata la sincronizzazione, trovo errori a non finire. In <code>/proc/mdstat</code> vedo marcato <code>&#091;F&#093; /dev/sdd1</code>, e ci sta, e <code>&#091;S&#093; /dev/sdb1</code>, che non ho approfondito cosa stia a identificare. 
<br />
<br />Spengo, collego il secondo disco di salvataggio, riparto con la MEPIS e riesco ad assemblare nuovamente l'array con lo stesso metodo, e termino le copie.
<br />
<br />Siccome ho sentito gi&#224; pi&#249; di una volta che mdadm <i>rompa</i> gli array senza un apparente valido motivo, anche se a me fin'ora non &#232; mai successo, disfo tutto e ricostruisco un RAID10 ex-novo:
<br />
<br /><code>mdadm --manage /dev/md0 --fail /dev/sda1
<br />mdadm --manage /dev/md0 --remove /dev/sda1</code>
<br />
<br />Ripetere questi due comandi per gli altri tre dischi, poi:
<br />
<br /><code>mdadm --manage --stop /dev/md0</code>
<br />
<br />Quindi creo il nuovo array:
<br />
<br /><code>mdadm --create /dev/md0 -v --raid-devices=4 --level=raid10 /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sdd1</code>
<br />
<br />Dopo circa tre ore di sincronizzazione, inizio a copiarci dentro circa 600 GB di dati.
<br />Al momento risultano ancora tutti <code>&#091;UUUU&#093;</code>, che sia stato veramente un <i>colpo di testa</i> di mdadm?
<br />
<br />Sto ora aggiornando l'intero sistema, tra cui anche mdadm, che da quasi due anni era alla versione di allora di Debian. Se sia stato un bug spero tanto che l'abbiano risolto.

<h3>Dopo l'aggiornamento a Squeeze...</h3>

I moduli del kernel vanno ricompilati in quanto &#232; stato installato il nuovo kernel 2.6.32. E' sufficiente seguire le istruzioni descritte nella <a href="http://wiki.debian.org/VMware#Installing_VMware_Server_2_on_Squeeze" target="_blank">Debian Wiki</a> per installare le patch e compilare i moduli correttamente.
<br />
<br />Le condivisioni pubbliche di samba non funzionavano pi&#249;. Problema noto, le ultime versioni di samba hanno per default un passdb backend diverso da <code>smbpasswd</code>. Aggiungendo la riga <code>passdb backend = smbpasswd</code> a <code>smb.conf</code> tutto si ripristina senza ricostruire nulla. ]]></content:encoded>

</item>

<item>
<title>System uptime su Windows, in stile Linux</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2012-01-system-uptime-su-windows-in-stile-linux?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2012-01-system-uptime-su-windows-in-stile-linux?open=feed#comments</comments>
<pubDate>Tue, 03 Jan 2012 20:32:02 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Windows]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2012-01-system-uptime-su-windows-in-stile-linux?open=feed</guid>

<description><![CDATA[ L'uptime, per com'&#232; conosciuto dai viziati Linux, su Windows manca e se ne sente la mancanza.
I comandi net statistics server o systeminfo riportano solamente la data e ora dell'ultimo avvio.
Questo file VBS legge data e ora di avvio e restituisce il tempo trascorso:
Set objShell = WScript.CreateObject(&quot;WScript.Shell&quot;)
Set objExecObject = objShell.Exec(&quot;cmd /c net statistics server&quot;)
lineNum = 1
strText = &quot;&quot;
Do While Not objExecObject. ]]></description>

<content:encoded><![CDATA[ L'uptime, per com'&#232; conosciuto dai viziati Linux, su Windows manca e se ne sente la mancanza.
<br />I comandi <code>net statistics server</code> o <code>systeminfo</code> riportano solamente la data e ora dell'ultimo avvio.
<br />
<br />Questo file VBS legge data e ora di avvio e restituisce il tempo trascorso:

<pre name="code" class="vb">Set objShell = WScript.CreateObject(&quot;WScript.Shell&quot;)
Set objExecObject = objShell.Exec(&quot;cmd /c net statistics server&quot;)
lineNum = 1
strText = &quot;&quot;
Do While Not objExecObject.StdOut.AtEndOfStream
    strText = Trim(objExecObject.StdOut.ReadLine())
	If lineNum = 4 Then
		Exit Do
	End If
	lineNum = lineNum + 1
Loop

strDateTime = &quot;&quot;
For pos = 1 To Len(strText)
	ch = Right(Left(strText, pos), 1)
	If Asc(ch) &gt;= 48 And Asc(ch) &lt;= 57 Then
		strDateTime = Right(strText, Len(strText) - pos + 1)
		Exit For
	End If
Next

dt = CDate(strDateTime)

diffS = Datediff(&quot;s&quot;, dt, Now)

diffM = Fix(diffS / 60)
diffS = diffS - (diffM * 60)
diffH = Fix(diffM / 60)
diffM = diffM - (diffH * 60)
diffD = Fix(diffH / 24)
diffH = diffH - (diffD * 24)

Dim tokens()

bounds = 0

If diffD &gt; 0 Then
	Redim Preserve tokens(bounds)
	If diffD = 1 Then
		tokens(bounds) = &quot;1 day&quot;
	Else
		tokens(bounds) = diffD &amp; &quot; days&quot;
	End If
	bounds = bounds + 1
End If

If diffH &gt; 0 Then
	Redim Preserve tokens(bounds)
	If diffH = 1 Then
		tokens(bounds) = &quot;1 hour&quot;
	Else
		tokens(bounds) = diffH &amp; &quot; hours&quot;
	End If
	bounds = bounds + 1
End If

If diffM &gt; 0 Then
	Redim Preserve tokens(bounds)
	If diffM = 1 Then
		tokens(bounds) = &quot;1 minute&quot;
	Else
		tokens(bounds) = diffM &amp; &quot; minutes&quot;
	End If
	bounds = bounds + 1
End If

If diffS &gt; 0 Then
	Redim Preserve tokens(bounds)
	If diffS = 1 Then
		tokens(bounds) = &quot;1 second&quot;
	Else
		tokens(bounds) = diffS &amp; &quot; seconds&quot;
	End If
	bounds = bounds + 1
End If

WScript.Echo &quot;up &quot; &amp; Join(tokens, &quot;, &quot;)</pre>

<p align="center"><a href="http://flaz.biz/A55CEC/blog.nsf/0/368FA6C854844CA4C125797A0071737C/$FILE/uptime.gif" style="text-decoration:none"><img src="http://flaz.biz/A55CEC/blog.nsf/0/368FA6C854844CA4C125797A0071737C/$FILE/thumb.jpg" alt="uptime" /></a></p>

Ultimi giorni di ferie, gi&#224; mi manca il lavoro? :-) ]]></content:encoded>

</item>

<item>
<title>Stampare da command line con Acrobat Reader... o no?</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2011-10-stampare-da-command-line-con-acrobat-reader-o-no?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2011-10-stampare-da-command-line-con-acrobat-reader-o-no?open=feed#comments</comments>
<pubDate>Sat, 08 Oct 2011 15:44:09 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Java]]></category>

<category><![CDATA[Lotus]]></category>

<category><![CDATA[Windows]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2011-10-stampare-da-command-line-con-acrobat-reader-o-no?open=feed</guid>

<description><![CDATA[ Non ho avuto la curiosit&#224; di provare su altri sistemi oltre Windows 7 Professional e/o PDF reader oltre Adobe Reader X, ma qualcuno si &#232; mai accorto che selezionando 16 PDF non &#232; possibile lanciare la stampa da Esplora risorse?
Ci&#242; &#232; invece possibile selezionando fino a 15 PDF:
Pur restando entro questo limite, non tutti vengono stampati. E oltre tutto non nell'ordine di selezione. ]]></description>

<content:encoded><![CDATA[ Non ho avuto la curiosit&#224; di provare su altri sistemi oltre Windows 7 Professional e/o PDF reader oltre Adobe Reader X, ma qualcuno si &#232; mai accorto che selezionando 16 PDF non &#232; possibile lanciare la stampa da Esplora risorse?
<br />
<br /><a href="http://flaz.biz/A55CEC/blog.nsf/0/110291758B3AABC5C12579230059C63C/$FILE/16-selezionati.png" style="border:0"><img src="http://flaz.biz/A55CEC/blog.nsf/0/110291758B3AABC5C12579230059C63C/$FILE/thumb.jpg" alt="16 PDF selezionati" /></a>
<br />
<br />Ci&#242; &#232; invece possibile selezionando fino a 15 PDF:
<br />
<br /><a href="http://flaz.biz/A55CEC/blog.nsf/0/37C0398EDF840CFBC12579230059E84A/$FILE/15-selezionati.png" style="border:0"><img src="http://flaz.biz/A55CEC/blog.nsf/0/37C0398EDF840CFBC12579230059E84A/$FILE/thumb.jpg" alt="15 PDF selezionati" /></a>
<br />
<br />Pur restando entro questo limite, non tutti vengono stampati. E oltre tutto non nell'ordine di selezione.
<br />
<br />Il problema l'ho notato cercando una soluzione al quesito di un Cliente, il quale ha un database Notes che usa come archiviazione documentale, e spesso ha bisogno di stampare diverse decine di documenti, tutti in una volta. Una delle idee consisteva proprio nell'esportare i documenti richiesti in un percorso designato, e banalmente dall'Esplora risorse eseguire la stampa. Il massimo risultato con il minimo sforzo, insomma. Ma purtroppo non &#232; stato possibile.
<br />
<br />Passiamo alla seconda soluzione, un agente che in sequenza esporti i PDF e lanci Adobe Reader per la stampa via command line. Non tutti sanno che Adobe Reader pu&#242; essere eseguito da command line per stampare direttamente un PDF. La sintassi &#232; qualcosa del tipo:
<br />
<br /><code>AdoRd32.exe /p /h DOCUMENTO.PDF</code>
<br />
<br />Sarebbe ottimo, se esistesse un modo per far s&#236; che Adobe si chiuda da solo una volta terminato il processo di stampa.
<br />Per ovviare a ci&#242; avevo pensato di:

<ol>
<li>Avviare il comando di cui sopra;</li>
<li>Attendere, eseguendo in shell <a href="http://technet.microsoft.com/en-us/library/bb491010.aspx" target="_blank">tasklist</a>, che Adobe parta (facendo le dovute considerazioni circa il fatto che potrebbe essere gi&#224; attiva un'altra istanza di Adobe);</li>
<li>Ciclare fino a che il file PDF da stampare esiste su disco, e all'interno del ciclo tentare di eliminarlo: fino a che Adobe &#232; aperto lo blocca e l'eliminazione non va a buon fine. Nel momento in cui Adobe ha eseguito la stampa, <i>libera</i> il file e quindi ha luogo l'eliminazione che comporta l'uscita dal ciclo. Meglio comunque se controllato da un timeout;</li>
<li>Terminare Adobe, eseguendo in shell <a href="http://technet.microsoft.com/en-us/library/bb491009.aspx" target="_blank">taskkill</a>.</li>
</ol>

Arriva ora di pranzo e ci mangio sopra. La soluzione, che sulla carta dovrebbe essere funzionante, pecca per il solo fatto che &#232; troppo complicata per la banalit&#224; dell'operazione che deve eseguire. Inoltre, eseguire 100 stampe di 100 documenti &#232; ben pi&#249; lento di eseguire una stampa di un documento da 100 pagine.
<br />
<br />La pancia piena porta consiglio, cos&#236; decido di unire tutti i PDF in un unico file, e aprire quest'ultimo con Adobe Reader, dando oltretutto modo all'utente di stampare manualmente potendo quindi selezionare anche la stampante.
<br />Feci gi&#224; una cosa del genere qualche anno fa, con <a href="http://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/" target="_blank">pdftk</a>. Siccome per&#242; le librerie di iText gi&#224; le uso mi sono detto: perch&#233; non unire i PDF direttamente in Lotus con un semplice agente Java?
<br />
<br />Ho trovato anche una classe <a href="http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html" target="_blank"><code>MergePDF</code> gi&#224; scritta</a> che fa quasi esattamente quello che mi serve. Di fatto, la paginazione l'ho tolta perch&#233; per me inutile (e oltre tutto ho avuto delle eccezioni per font Helvetica non trovato eseguendo l'agente sul server Domino in ambiente Linux), e ho preferito ottenere il PDF unico come byte array restituito dalla funzione, anzich&#233; dover passare un <code>OutputStream</code>. Questo &#232; quello che ne &#232; uscito:

<pre name="code" class="java">import com.lowagie.text.Document;
import com.lowagie.text.pdf.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class MergePDF {

  public static byte&#091;&#093; concatPDFs(List&lt;InputStream&gt; streamOfPDFFiles) {

	byte&#091;&#093; ret = null;
	  
    Document document = new Document();
    try {
      List&lt;InputStream&gt; pdfs = streamOfPDFFiles;
      List&lt;PdfReader&gt; readers = new ArrayList&lt;PdfReader&gt;();
      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      int totalPages = 0;
      Iterator&lt;InputStream&gt; iteratorPDFs = pdfs.iterator();

      // Create Readers for the pdfs.
      while (iteratorPDFs.hasNext()) {
        InputStream pdf = iteratorPDFs.next();
        PdfReader pdfReader = new PdfReader(pdf);
        readers.add(pdfReader);
        totalPages += pdfReader.getNumberOfPages();
      }
      // Create a writer for the outputstream
      PdfWriter writer = PdfWriter.getInstance(document, outputStream);

      document.open();
      PdfContentByte cb = writer.getDirectContent(); // Holds the PDF
      // data

      PdfImportedPage page;
      int currentPageNumber = 0;
      int pageOfCurrentReaderPDF = 0;
      Iterator&lt;PdfReader&gt; iteratorPDFReader = readers.iterator();

      // Loop through the PDF files and add to the output.
      while (iteratorPDFReader.hasNext()) {
        PdfReader pdfReader = iteratorPDFReader.next();

        // Create a new page in the target for each source page.
        while (pageOfCurrentReaderPDF &lt; pdfReader.getNumberOfPages()) {
          document.newPage();
          pageOfCurrentReaderPDF++;
          currentPageNumber++;
          page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
          cb.addTemplate(page, 0, 0);
        }
        pageOfCurrentReaderPDF = 0;
      }
      outputStream.flush();
      document.close();
      outputStream.close();
      
      ret = outputStream.toByteArray();
      
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (document.isOpen())
        document.close();
    }
    
    return ret;
    
  }
  
}</pre>

Mettendo insieme tutti i pezzi il risultato &#232; perfetto e veloce.
<br />
<br />Per collaudarlo l'ho implementato nel mio Gestionale, che &#232; una gran comodit&#224; per quando devo stampare le fatture del trimestre da consegnare al commercialista! ]]></content:encoded>

</item>

<item>
<title>Modalità documento IE8 e offsetHeight</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2011-09-modalita-documento-ie8-e-offsetheight?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2011-09-modalita-documento-ie8-e-offsetheight?open=feed#comments</comments>
<pubDate>Tue, 27 Sep 2011 13:07:16 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Web]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2011-09-modalita-documento-ie8-e-offsetheight?open=feed</guid>

<description><![CDATA[ Quest'estate mi sono dedicato allo sviluppo di un portale interno web per un'azienda della zona. Motore Domino, ma rendering HTML ad hoc. Le XPages le ho escluse, troppe complicazioni per far quadrare le cose. In realt&#224; le sto ancora evitando del tutto, non mi vanno molto gi&#249; a dire il vero.
La prima installazione di IE9 chiede all'utente se attivare o meno la modalit&#224; compatibilit&#224;, che per impostazione predefinita assume che tutti i siti vengano renderizzati secondo gli standard di IE7. ]]></description>

<content:encoded><![CDATA[ Quest'estate mi sono dedicato allo sviluppo di un portale interno web per un'azienda della zona. Motore Domino, ma rendering HTML ad hoc. Le XPages le ho escluse, troppe complicazioni per far quadrare le cose. In realt&#224; le sto ancora evitando del tutto, non mi vanno molto gi&#249; a dire il vero.
<br />
<br />La prima installazione di IE9 chiede all'utente se attivare o meno la modalit&#224; compatibilit&#224;, che per impostazione predefinita assume che tutti i siti vengano renderizzati secondo gli standard di IE7.
<br />Ho imposto tramite la <a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc288325%28v=vs.85%29.aspx">Document Compatibility</a> (un banale header HTTP) lo standard IE8, garantendomi quindi un minimo di retrocompatibilit&#224;, oltre che ovviamente pieno supporto per la versione 9.
<br />
<br />Tutto il portale risulta perfettamente funzionante in modalit&#224; documento IE8, eccetto un particolare. La propriet&#224; <code>offsetHeight</code> di un nodo appena creato via AJAX, ritorna inesorabilmente zero.
<br />
<br />Per un elemento, creato e popolato dalla stessa chiamata AJAX, non &#232; possibile leggere in nessun modo l'altezza attraverso la propriet&#224; di cui sopra.
<br />Riprodurre l'errore &#232; semplice:

<pre name="code" class="js">document.appendChild(new Element('div', { 'id' : 'popup' }));
for (var i = 0; i &lt; 10; i++) $('popup').appendChild(new Element(p).update('prova'));

if ($('popup').offsetHeight + $('popup').offsetTop &gt; browserHeight)
	$('popup').style.bottom = '50px';</pre>

La logica dovrebbe essere quella di imporre un'altezza fissa all'elemento <code>#popup</code> qualora la sua altezza superasse l'altezza della finestra del browser. Cosa che su IE9 o Firefox funziona divinamente.
<br />
<br />L'unica soluzione che ho trovato &#232; stata quella di <b>ritardare</b> temporalmente la lettura dell'altezza dell'elemento <code>#popup</code>. In questo modo IE8 &#232; in grado di restituire il valore corretto. Vale a dire:

<pre name="code" class="js">document.appendChild(new Element('div', { 'id' : 'popup' }));
for (var i = 0; i &lt; 10; i++) $('popup').appendChild(new Element(p).update('prova'));

setTimeout('resizePopup()', 100);</pre>

La funzione <code>resizePopup</code> (definita non nella risposta AJAX ma nel documento <i>chiamante</i>) non &#232; altro che un taglia-incolla del codice originale:

<pre name="code" class="js">function resizePopup() {
	if ($('popup').offsetHeight + $('popup').offsetTop &gt; browserHeight)
		$('popup').style.bottom = '50px';
}</pre>

Il motivo di ci&#242;? In modalit&#224; IE8 l'altezza dell'elemento <code>#popup</code> viene letta <b>prima</b> che vengano applicati i contenuti all'elemento stesso, fregandosene altamente della sequenza con cui le operazioni sono state scritte. ]]></content:encoded>

</item>

<item>
<title>Backup verde</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2011-08-backup-verde?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2011-08-backup-verde?open=feed#comments</comments>
<pubDate>Mon, 08 Aug 2011 07:59:57 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Windows]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2011-08-backup-verde?open=feed</guid>

<description><![CDATA[ In ufficio ho due server: il principale (ESXi e poco meno di una dozzina di macchine virtuali), e un server PC dedicato al backup, un vecchio Lenovo 3000 J Series.
D'estate la temperatura comincia a diventare un problema, soprattutto il luned&#236; mattina dopo la chiusura del fine settimana.
Il server VMware non pu&#242; essere spento, al contrario per&#242; il PC di backup lavora solamente qualche ora durante la notte. ]]></description>

<content:encoded><![CDATA[ In ufficio ho due server: il principale (ESXi e poco meno di una dozzina di macchine virtuali), e un <strike>server</strike> PC dedicato al backup, un vecchio Lenovo 3000 J Series.
<br />
<br />D'estate la temperatura comincia a diventare un problema, soprattutto il luned&#236; mattina dopo la chiusura del fine settimana.
<br />Il server VMware non pu&#242; essere spento, al contrario per&#242; il PC di backup lavora solamente qualche ora durante la notte.
<br />Inutile dire che rendere l'operazione accendi/spegni manuale &#232; improponibile: tra dimenticanze e trasferte dai clienti finirebbe che i salvataggi si eseguirebbero solo poche volte al mese.
<br />
<br />Ho cos&#236; deciso di automatizzare le cose attraverso il <b>Wake On LAN</b> (nel BIOS di questa scheda madre definito <i>PME Wake Up Event</i>), chiaramente comandato dal server VMware.
<br />Dovendo abbozzare un flusso sarebbe pi&#249; o meno cos&#236;:

<ul>
<li>23.10: il server di dominio accende il PC di backup</li>
<li>23.30: il PC di backup salva su supporto esterno i dati della nottata precedente</li>
<li>00.00 - 02.00 circa: i vari server virtuali copiano i propri dati sul PC di backup</li>
<li>3.30: il PC di backup si spegne</li>
</ul>

Il cosiddetto <i>Magic Packet</i> pu&#242; essere inviato da riga di comando e quindi automatizzato attraverso le operazioni pianificate di Windows. L'utility che ho usato &#232; <a href="http://www.depicus.com/wake-on-lan/wake-on-lan-cmd.aspx" target="_blank"><b>WolCmd</b></a>, richiamata da un semplice file batch:
<br />
<br /><code>WolCmd.exe 00148577cccf 172.20.255.255 255.255.0.0 8900</code>
<br />
<br />Alle 3.30 di notte il PC di backup si spegner&#224;, sulla base dell'operazione pianificata di shutdown:
<br />
<br /><code>shutdown /p /f</code>
<br />
<br />Diventa backup verde proprio perch&#233; i 3/4 del tempo che il PC era acceso non faceva assolutamente nulla, consumando inutilmente corrente e riscaldando l'ambiente comportando un ulteriore successivo consumo per il raffrescamento.
<br />
<br />Come nota negativa il continuo accendi e spegni giornaliero che sicuramente stresser&#224; alimentatore e dischi accorciandone la vita. ]]></content:encoded>

</item>

<item>
<title>Stampanti locali in Terminal Server su 2008 R2 64-bit</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2011-07-stampanti-locali-in-terminal-server-su-2008-r2-64-bit?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2011-07-stampanti-locali-in-terminal-server-su-2008-r2-64-bit?open=feed#comments</comments>
<pubDate>Fri, 29 Jul 2011 18:55:33 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Windows]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2011-07-stampanti-locali-in-terminal-server-su-2008-r2-64-bit?open=feed</guid>

<description><![CDATA[ La scorsa settimana ho migrato il Server di un Cliente da 2003 32-bit a 2008 R2 64-bit.
Utenti della filiale estera si collegano a tale Server in Desktop Remoto per lavorare sul Gestionale localmente installato, collegando le stampanti locali.
Pur seguendo il classico iter per la configurazione delle stampanti in Terminal Server a cui mi sono abituato su Windows 2003, in questo caso nulla da fare. ]]></description>

<content:encoded><![CDATA[ La scorsa settimana ho migrato il Server di un Cliente da 2003 32-bit a 2008 R2 64-bit.
<br />
<br />Utenti della filiale estera si collegano a tale Server in Desktop Remoto per lavorare sul Gestionale localmente installato, collegando le stampanti locali.
<br />
<br />Pur seguendo il classico iter per la configurazione delle stampanti in Terminal Server a cui mi sono abituato su Windows 2003, in questo caso nulla da fare.
<br />Le stamanti si collegano, le stampe partono senza alcun errore, la coda di stampa si vuota ma la stampante fisicamente non muove foglio.
<br />
<br />Nessun errore o traccia nei registri, n&#233; del Server e n&#233; del Client. Per entrambi va tutto benissimo.
<br />
<br />Da documentazione Microsoft l'unico <i>Come risolvere</i> consiste nell'assegnare i permessi alla directory di spool. Permessi che, nel mio caso, sono gi&#224; corretti.
<br />Nemmeno Google mi aiuta. Ormai la concentrazione &#232; persa, e con essa probabilmente anche la mia capacit&#224; di fare una banale ricerca, del resto sono le 2 di notte. Meglio dormirci sopra e tornare sul problema la mattina seguente.
<br />
<br />Dopo alcune altre prove disperate e, lo ammetto, casuali, ho, con una gran dose di fortuna, indovinato la soluzione al problema spostando la directory di spool da <code>c:\windows\system32\spool</code> a <code>c:\spool</code>.
<br />
<br />Pochi giorni dopo ho avuto modo di sentire, per altri motivi, un Sistemista certificato Microsoft che conosco sufficientemente bene, sottoponendogli il problema e la soluzione che ho trovato.
<br />La spiegazione che mi ha dato si basa sul fatto che la directory <code>windows</code>, e sottodirectory, non prevede la modifica dei file in nessun caso se l'utente non appartiene al gruppo Administrators, anche se il gruppo Print Operators (di cui sono membri gli utenti terminal) ha pieno potere sulla directory di spool, tale <i>politica di sicurezza</i> prevale sui permessi specificati. ]]></content:encoded>

</item>

<item>
<title>Apache su Debian vs CentOS</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2011-06-apache-su-debian-vs-centos?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2011-06-apache-su-debian-vs-centos?open=feed#comments</comments>
<pubDate>Mon, 27 Jun 2011 09:12:29 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[GNU/Linux]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2011-06-apache-su-debian-vs-centos?open=feed</guid>

<description><![CDATA[ Sono sempre stato un fedele utilizzatore di Debian, soprattutto per il fatto che non ho mai avuto problemi di sorta per i quali non trovassi soluzione.
Recentemente sto sviluppando un progetto su Magento per il quale ho sfruttato l'ambiente di sviluppo web che ho sul server. Una normale installazione di Debian Lenny su VMware con Apache, PHP e MySQL. Con Samba accedo direttamente a /var/www e cos&#236; ho sempre lavorato egregiamente. ]]></description>

<content:encoded><![CDATA[ Sono sempre stato un fedele utilizzatore di Debian, soprattutto per il fatto che non ho mai avuto problemi di sorta per i quali non trovassi soluzione.
<br />
<br />Recentemente sto sviluppando un progetto su <a href="http://www.magentocommerce.com/">Magento</a> per il quale ho sfruttato l'ambiente di sviluppo web che ho sul server. Una normale installazione di Debian Lenny su VMware con Apache, PHP e MySQL. Con Samba accedo direttamente a <code>/var/www</code> e cos&#236; ho sempre lavorato egregiamente.
<br />
<br />Nella Lenny, per&#242;, ho sempre notato una particolare lentezza di Apache, particolarmente nei momenti in cui interroga il database. CPU esageratamente sotto stress senza un sensato motivo.
<br />Magento, che gi&#224; di suo &#232; un bel <i>mattone</i>, in un ambiente gi&#224; problematico &#232; ai limiti dell'usabilit&#224;. Nel senso che spesso banali chiamate WSDL finiscono in timeout. Della serie: impiego un'ora per svolgere operazioni che normalmente potrebbero richiedere la met&#224; del tempo, o anche meno.
<br />
<br /><i>Googlando</i> non ho trovato soluzioni al mio problema, ci sono diverse lamentele nei forum circa la lentezza di Apache, ma nessuno che fosse in grado di risolvere il problema. Ho aggiornato il sistema a Debian 6, forse migliorando di poco la situazione. Ma obiettivamente potrebbe anche essere effetto placebo. Facendo un po' di debug di Apache non ne sono venuto a capo.
<br />
<br />Red Hat e derivate non le ho mai gradite particolarmente, soprattutto per il fatto che la gestione dei pacchetti &#232; decisamente peggiore rispetto ad Aptitude. Ma d'altra parte sono stato quasi costretto ad utilizzare CentOS gi&#224; da anni per via di installazioni di Lotus Domino su S/O GNU/Linux quindi non sono proprio nuovo su queste distribuzioni.
<br />
<br />Ho cos&#236; trascorso il sabato mattina a installare una nuova VM con CentOS, installando tutti i pacchetti del caso (Apache, PHP, MySQL, Samba) e facendo quelle poche, ma necessarie, configurazioni del caso.

<h3>Primo problema</h3>

Ho copiato <code>smb.conf</code> dal vecchio sistema Debian a CentOS. Una brutale condivisione pubblica della <code>/var/www</code> che ha sempre funzionato. Su CentOS nulla da fare. Dopo qualche ricerca ho capito che il responsabile era <b>SELinux</b>, il quale, quando attivato, inibisce tra le altre cose la possibilit&#224; di condividere directory quali <code>/home</code> e <code>/var</code>. Senza troppi scrupoli ho brutalmente disattivato SELinux, sicuro comunque del fatto che la macchina non &#232; pubblicata su internet.
<br />
<br />Il file da modificare &#232; <code>/etc/selinux/config</code>, definendo <code>disabled</code> alla variabile <code>SELINUX</code>.

<h3>Secondo problema</h3>

Il pacchetto <code>php</code> di CentOS contiene PHP in versione 5.1.6. Magento necessita di PHP versione 5.2.0 o successive. Poco male, si installa la 5.3, comunque disponibile ma in un pacchetto a parte:
<br />
<br /><code># yum remove php php-*
<br /># yum install php53 php53-mysql php53-gd php53-xml php53-cli</code>

<h3>Terzo problema</h3>

Magento ora &#232; felice di avere la versione di PHP corretta, ma si lamenta del fatto che l'estensione <b>mcrypt</b> non &#232; installata. Estensione che, nella versione 5.3 di PHP, non &#232; presente nei repository di CentOS!
<br />
<br />Dai forum di CentOS trovo un <a href="http://www.how2centos.com/installing-php-5-3-3-on-centos-5-5-tutorial/">Tutorial</a> in grado di risolvere il problema, che, brevemente, consiste nel disinstallare (un'altra volta) PHP 5.3 e installare una versione <i>u</i> proveniente da diversi repository.

<h3>Risolti tutti i problemi...</h3>

Effettivamente ora Magento viaggia a velocit&#224; accettabile. Com'era gi&#224; noto, non &#232; un fulmine in velocit&#224; gi&#224; di suo, ma la versione di Apache presente in Debian lo rallentava ulteriormente, e non di poco.
<br />
<br />Adesso posso finalmente tornare a sviluppare in un ambiente <b>veloce</b>! ]]></content:encoded>

</item>

<item>
<title>L'ex alfista</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2011-03-l-ex-alfista?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2011-03-l-ex-alfista?open=feed#comments</comments>
<pubDate>Fri, 25 Mar 2011 18:06:29 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Blogging]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2011-03-l-ex-alfista?open=feed</guid>

<description><![CDATA[ Con immenso dispiacere, oggi il nuovo proprietario &#232; venuto a portarla via:
A distanza di quattro anni da quando l'acquistai, e da molti di pi&#249; da quando iniziai ad apprezzarla, credo ancora oggi che sia un'auto davvero notevole. Da intenditori! ]]></description>

<content:encoded><![CDATA[ Con immenso dispiacere, oggi il nuovo proprietario &#232; venuto a portarla via:

<p align="center"><a style="border:0" href="http://flaz.biz/A55CEC/blog.nsf/0/3E18CE49A1F87F2EC125785E00641AD1/$FILE/100_1118.jpg"><img src="http://flaz.biz/A55CEC/blog.nsf/0/3E18CE49A1F87F2EC125785E00641AD1/$FILE/thumb.jpg" alt="GTV" /></a></p>

A distanza di quattro anni da quando l'acquistai, e da molti di pi&#249; da quando iniziai ad apprezzarla, credo ancora oggi che sia un'auto davvero notevole. Da intenditori! ]]></content:encoded>

</item>

<item>
<title>Domino Designer 8.5: bug nelle base classes</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2011-03-domino-designer-8-5-bug-nelle-base-classes?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2011-03-domino-designer-8-5-bug-nelle-base-classes?open=feed#comments</comments>
<pubDate>Wed, 09 Mar 2011 13:08:07 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Lotus]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2011-03-domino-designer-8-5-bug-nelle-base-classes?open=feed</guid>

<description><![CDATA[ Non spesso mi capita di utilizzare le base classes in Lotus Domino. Probabilmente l'ultima volta che le ho utilizzate &#232; stato su vecchie release, forse addirittura R7.
L'uso &#232; banale, soprattutto per chi &#232; gi&#224; stato abituato all'ereditariet&#224; delle classi in C o Java. In LotusScript il concetto non &#232; in fin dei conti molto diverso:
Public Class Persona
	Public Nome As String
	Public Cognome As String
	Sub New(nome As String, cognome As String)
		Me. ]]></description>

<content:encoded><![CDATA[ Non spesso mi capita di utilizzare le <b>base classes</b> in Lotus Domino. Probabilmente l'ultima volta che le ho utilizzate &#232; stato su vecchie release, forse addirittura R7.
<br />
<br />L'uso &#232; banale, soprattutto per chi &#232; gi&#224; stato abituato all'ereditariet&#224; delle classi in C o Java. In LotusScript il concetto non &#232; in fin dei conti molto diverso:

<pre class="vb" name="code">Public Class Persona
	Public Nome As String
	Public Cognome As String
	Sub New(nome As String, cognome As String)
		Me.Nome = nome
		Me.Cognome = cognome
	End Sub
End Class

Public Class Dipendente As Persona
	Public Matricola As Integer
	Sub SetMatricola(num As Integer)
		Me.Matricola = num
	End Sub
End Class</pre>

Dopo aver scritto due classi <i>ConsumiMese</i> e <i>ConsumiBimestre</i> che ereditano da <i>ConsumiBaseClass</i>, noto che entrambe non vengono compilate con successo:

<p align="center"><a style="border-bottom:0 !important" href="http://flaz.biz/A55CEC/blog.nsf/0/B74E1891FC46AE52C125784E004A2778/$FILE/baseclass.jpg"><img src="http://flaz.biz/A55CEC/blog.nsf/0/B74E1891FC46AE52C125784E004A2778/$FILE/thumb.jpg" alt="Base Class" /></a></p>

L'errore &#232; &quot;Reference appears before declaration&quot;.
<br />Tentativi di tagliare e incollare le classi sopra o sotto non hanno avuto effetto, n&#232; provare nomi particolari al fine di posizionare la base class prima o dopo la <i>ConsumiMese</i>.
<br />
<br />Non sono per&#242; l'unico ad aver riscontrato il problema: &#232; gi&#224; stato <a href="http://www-10.lotus.com/ldd/nd85forum.nsf/0/3e1d1936e486dbff852576d90023b801?OpenDocument" target="_blank">reso noto</a> nel Forum della 8.5 gi&#224; da diversi mesi.
<br />
<br />La soluzione consiste nel servirsi di una nuova libreria, che ho deciso di usare come contenitore per tutte le base classes, denominata <i>BaseClasses</i>.
<br />Al suo interno verr&#224; inserita la classe <i>ConsumiBaseClass</i>, lasciando quindi solamente <i>ConsumiMese</i> e <i>ConsumiBimestre</i> nella libreria <i>Consumi</i>.
<br />Non resta altro da fare che includere la <i>BaseClasses</i> all'interno della libreria <i>Consumi</i>:

<pre class="vb" name="code">Include &quot;BaseClasses&quot;</pre>

Avendo quindi la base class esterna alla libreria da dove la stessa viene richiamata, l'errore scompare e le classi vengono correttamente compilate. ]]></content:encoded>

</item>

<item>
<title>TP-LINK WA901ND e WN821N</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2011-03-tp-link-wa901nd-e-wn821n?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2011-03-tp-link-wa901nd-e-wn821n?open=feed#comments</comments>
<pubDate>Tue, 08 Mar 2011 19:21:47 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Networking]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2011-03-tp-link-wa901nd-e-wn821n?open=feed</guid>

<description><![CDATA[ A Gennaio scrissi che il vecchio D-Link DAP-1160 aveva i giorni contati.
Ebbene, gi&#224; da un mese l'AP di cui sopra l'ho messo in soffitta, e il suo posto &#232; stato preso da uno sconosciuto: TP-LINK.
Ho acquistato il TP-WA901ND, e insieme anche la chiavetta per il PC fisso TP-WN821N, in sostituzione a una vecchia Conceptronic 802.11n 150 Mbps.
Ho ignorato, all'atto dell'acquisto, che il WA901ND viene fornito con il POE injector, cosa che ho molto apprezzato solo dopo aver aperto la confezione e che mi ha permesso di appendere fisicamente l'AP al muro sopra alla scatola da cui arriva il ]]></description>

<content:encoded><![CDATA[ A Gennaio scrissi che il vecchio D-Link DAP-1160 <a href="http://flaz.biz/A55CEC/blog.nsf/post/2011-01-montare-un-immagine-dd-di-un-intero-disco">aveva i giorni contati</a>.
<br />
<br />Ebbene, gi&#224; da un mese l'AP di cui sopra l'ho messo in soffitta, e il suo posto &#232; stato preso da uno sconosciuto: TP-LINK.
<br />
<br />Ho acquistato il <a href="http://www.tp-link.com/en/products/prodetail.aspx?mid=010303010102&amp;id=406" target="_blank">TP-WA901ND</a>, e insieme anche la chiavetta per il PC fisso <a href="http://www.tp-link.com/en/products/prodetail.aspx?mid=010303010103&amp;id=128" target="_blank">TP-WN821N</a>, in sostituzione a una vecchia Conceptronic 802.11n 150 Mbps.
<br />
<br />Ho ignorato, all'atto dell'acquisto, che il WA901ND viene fornito con il <b><abbr title="Power Over Ethernet">POE</abbr> injector</b>, cosa che ho molto apprezzato solo dopo aver aperto la confezione e che mi ha permesso di appendere fisicamente l'AP al muro sopra alla scatola da cui arriva il cavo Ethernet. Qui una foto della prima accensione:

<p align="center"><a style="border-bottom:0 !important" href="http://flaz.biz/A55CEC/blog.nsf/0/32F46A43867012B8C125784D006B331A/$FILE/tplink_pila.jpg"><img src="http://flaz.biz/A55CEC/blog.nsf/0/32F46A43867012B8C125784D006B331A/$FILE/thumb.jpg" alt="TP-LINK" /></a></p>

Degna di nota la pila di CD a sostengo dell'AP!
<br />
<br />In definitiva l'AP &#232; stato cos&#236; posizionato:

<p align="center"><a style="border-bottom:0 !important" href="http://flaz.biz/A55CEC/blog.nsf/0/D4A44D418DBFA59CC125784D006C5DEF/$FILE/tplink.jpg"><img src="http://flaz.biz/A55CEC/blog.nsf/0/D4A44D418DBFA59CC125784D006C5DEF/$FILE/thumb.jpg" alt="TP-LINK" /></a></p>

Il segnale &#232; ottimo, in alto sul muro della mia camera copro egregiamente tutta la casa.
<br />
<br />Un'altra funzione relativamente comoda del WA901ND &#232; il <a target="_blank" href="http://www.tp-link.com/support/showfaq.asp?id=171"><b>QSS</b></a>, una sorta di <i>wizard</i> di configurazione per i client. Cosa che per&#242; ho deciso di non utilizzare, e pu&#242; essere tranquillamente disabilitata dall'interfaccia web di amministrazione.
<br />Approposito di interfaccia web di amministrazione, due parole le voglio spendere su questo aspetto. A mio avviso le interfacce devono essere soprattutto veloci, immediate e chiare. La grafica e i <i>fronzoli</i> non servono. Cosa ancora pi&#249; odiosa la lentezza, o come per i pi&#249; recenti D-Link il fatto che si debbano riavviare anche per modificare una virgola. Il TP-LINK in oggetto vanta un ottimo <i>mini-sito</i> per la gestione. Minimale, veloce, intuitivo e chiaro. Cos&#236; dovrebbero farli, sempre.
<br />
<br />Riguardo la chiavetta WN821N c'&#232; poco da dire. Apprezzabile la prolunga USB per portare la stessa sopra alla scrivania. I driver non sono pesanti o invadenti, e Windows 7 64-bit &#232; supportato senza problemi.
<br />
<br />La velocit&#224; &#232; soddisfacente, ma c'&#232; da dire che la mia attuale rete Ethernet viaggia a 100 Mbps, e la rete wireless a 300 Mbps non pu&#242; che saturarla, per cui non sono attualmente in grado di dire se sia in grado di superare la soglia dei 12 Mb/s, che &#232; comunque una buona velocit&#224; in rete senza fili.
<br />
<br />Ultimo ma non meno importante l'aspetto prezzo: i TP-LINK hanno dei prezzi davvero competitivi, circa met&#224; rispetto a brand molto pi&#249; blasonati, e per la fascia di mercato SOHO non hanno nulla da invidiare a nessun'altro.
<br />Con circa <b>60 Euro</b> ho acquistato sia AP che chiavetta, per uso domestico o per piccoli studi o uffici sono decisamente ottimi, e soprattutto per quanto abbia avuto modo di vedere e provare personalmente non credo esistano altri prodotti con lo stesso rapporto qualit&#224;/prezzo.
<br />
<br />Di recente TP-LINK ha aperto una sede anche in Italia, a Milano, ed esiste un <a href="http://www.tplink-forum.it/" target="_blank">Forum di supporto</a> (anche se non ufficiale) in lingua italiana. ]]></content:encoded>

</item>

<item>
<title>Ma quanto sono efficaci le mie regole? Svolgimento</title>
<link>http://flaz.biz/A55CEC/blog.nsf/post/2011-03-ma-quanto-sono-efficaci-le-mie-regole-svolgimento?open=feed</link>
<comments>http://flaz.biz/A55CEC/blog.nsf/post/2011-03-ma-quanto-sono-efficaci-le-mie-regole-svolgimento?open=feed#comments</comments>
<pubDate>Sat, 05 Mar 2011 10:58:21 GMT</pubDate>
<dc:creator>Massimo</dc:creator>

<category><![CDATA[Posta Elettronica]]></category>

<guid isPermaLink="false">http://flaz.biz/A55CEC/blog.nsf/post/2011-03-ma-quanto-sono-efficaci-le-mie-regole-svolgimento?open=feed</guid>

<description><![CDATA[ Un paio di mesi fa ho scritto e implementato uno script per raccogliere i dati di utilizzo delle regole di SpamAssassin.
E' passata una quantit&#224; di tempo sufficiente per cominciare a dare un senso ai dati e cominciare a interpretarli.
Il mio scopo &#232; quello di ottenere un sistema che, nel tempo, mi dia un'idea dell'andamento di ciascuna regola. Andamento inteso come efficacia, cio&#232; quanto sbaglia (o quanto &#232; precisa) ciascuna regola, col fine di aumentare o diminuire il punteggio a seconda dei risultati o, se opportuno, rimuovere del tutto la regola quando non risulta esser ]]></description>

<content:encoded><![CDATA[ Un paio di mesi fa ho scritto e implementato uno <a href="http://flaz.biz/A55CEC/blog.nsf/post/2011-01-ma-quanto-sono-efficaci-le-mie-regole">script per raccogliere i dati di utilizzo delle regole di SpamAssassin</a>.
<br />
<br />E' passata una quantit&#224; di tempo sufficiente per cominciare a dare un senso ai dati e cominciare a interpretarli.
<br />
<br />Il mio scopo &#232; quello di ottenere un sistema che, nel tempo, mi dia un'idea dell'andamento di ciascuna regola. Andamento inteso come efficacia, cio&#232; <i>quanto sbaglia</i> (o <i>quanto &#232; precisa</i>) ciascuna regola, col fine di aumentare o diminuire il punteggio a seconda dei risultati o, se opportuno, rimuovere del tutto la regola quando non risulta essere per nulla efficace.
<br />
<br />Sono arrivato alla conclusione che le cose da considerare sono due: efficacia e frequenza. Entrambe, poi, dovranno essere <i>messe insieme</i> per dare un mix percentuale pesato in funzione dell'importanza di ciascuno dei due concetti.
<br />
<br />Riepilogando, io ho a disposizione, per ogni giorno e per ogni regola, il numero di e-mail identificate come spam e come ham nelle quali la relativa regola ha preso parte.
<br />
<br />L'efficienza la calcolo come segue:
<br />
<br />Efficienza = (Spam - Ham) / (Spam + Ham)
<br />dove Spam &gt; Ham
<br />
<br />Efficienza = (Ham - Spam) / (Spam + Ham)
<br />dove Ham &gt; Spam
<br />
<br />Che mi dar&#224; un'efficienza del 100% per quelle regole con Spam (o Ham) pari a zero.
<br />Mentre, regole che compaiono un pari numero di volte sia nelle e-mail risultanti essere spam e ham avranno efficienza zero.
<br />
<br />Il concetto di frequenza &#232; integrativo per pesare correttamente l'efficienza. Mi spiego:

<table border="1" cellspacing="1" cellpadding="0">
<tr>
<th>Spam</th>
<th>Ham</th>
<th>Efficienza</th>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>100%</td>
</tr>
<tr>
<td>100</td>
<td>0</td>
<td>100%</td>
</tr>
</table>

E' matematicamente corretto che in entrambi i casi l'efficienza sia del 100%, ma &#232; chiaro che la regola che compare pi&#249; frequentemente &#232; pi&#249; affidabile. E, per estensione del concetto, una regola che avesse come spam 99 e come ham 1 ha, secondo me, una maggiore affidabilit&#224; rispetto alla regola spam 1 e ham 0.
<br />
<br />Per calcolare la frequenza ho calcolato il numero totale di ricorrenze di tutte le regole, ovvero la sommatoria di Spam e Ham di tutte le regole nel giorno di riferimento.
<br />
<br />La frequenza andr&#242; quindi a calcolarla come segue:
<br />
<br />Frequenza = (Spam + Ham) / (Totale)
<br />dove Totale &#232; la sommatoria di Spam + Ham di tutte le regole.
<br />
<br />Fatto ci&#242;, non mi sono limitato a moltiplicare Efficienza * Frequenza, in quanto le due cose devono avere pesi diversi.
<br />La formula che sto utilizzando ora, e che a mio avviso &#232; sufficientemente valida, &#232; la seguente:
<br />
<br />Mix = Efficienza * 70 + Frequenza * 30
<br />
<br />L'efficienza ha un peso del 70% sul mix finale, mentre la frequenza assume un ruolo s&#236; importante, ma marginale.
<br />
<br />Al momento sto volutamente escludendo le regole con frequenza minima, per due motivi. Il primo consiste nell'escludere le regole che compaiono troppe poche volte per poter avere un Mix affidabile: &#232; possibile che una regola prenda parte a due scansioni soltando e sbagli entrambe le volte, non &#232; quindi giusto concederle una efficienza del 100%. Il secondo ha come unico scopo limitare il numero di dati, in quanto giornalmente le regole che prendono parte alle scansioni sono diverse centinaia, e per semplicit&#224; di lettura (comunque collegata alla prima motivazione) &#232; pi&#249; semplice considerare solamente le regole pi&#249; frequenti, almeno in questa fase.
<br />
<br />Lo step successivo consister&#224; nella rappresentazione grafica dei dati, per avere a colpo d'occhio l'andamento nel tempo di ciascuna regola e, parallelamente, il confronto tra le regole stesse per poter determinare una soglia media di affidabilit&#224; (Mix &gt; <i>x</i>). ]]></content:encoded>

</item>


</channel>

</rss>
