lunedì 28 febbraio 2011

Netstat: ricavare informazioni sulla rete

Dal man di netstat:
Netstat prints information about the Linux networking subsystem.
Si tratta di un comodo comando che permette di ottenere informazioni sul sistema di rete.

Lanciando il comando senza parametri vengono visualizzati i socket unix aperti e le connessioni internet attive (connessione ai server di posta, dns, etc)

Se invece si volessero visualizzare i socket aperti verso l'esterno (in ascolto) è necessario passare qualche altro parametro. Il comando

netstat -l --inet


mostra i socket aperti, ma è lento poiché esegue delle query dns per risalire al nome del dominio a partire dall'indirizzo IP. Usando il parametro -n, netstat mostrerà direttamente gli indirizzi IP e i numeri delle porte.

Se oltre a sapere quali socket sono attivi, si vuole sapere quali processi li stanno utilizzando, il comando

netstat -p -n -l --inet

permette di scoprirlo.

I parametri utilizzati finora sono:
-p stampa il nome del programma e il pid del processo principale
-n stampa indirizzi numerici al posto di nomi di host, tipi di porte e nomi utente
-l stampa solo i socket in ascolto (normalmente questa opzione non è attiva)
--inet stampa solo i socket di tipo inet (i classici socket tcp/udp); esclude la visualizzazione dei socket unix

Altri parametri utili sono:
-e visualizza informazioni estese (utente esecutore del processo, etc)
-c netstat rimane in esecuzione e ogni secondo mostra l'informazione richiesta
--tcp visualizza solo i socket TCP
--udp visualizza solo i socket UDP
-4 visualizza solo i socket via IPv4
-6 visualizza solo i socket via IPv6

mercoledì 9 febbraio 2011

ScrollableComposite: quello che la documentazione non dice

Come dice la documentazione, lo ScrolledComposite consente di visualizzare il suo contenuto con lo scorrimento delle barre verticali e orizzontali.

La documentazione è abbastanza dettagliata, fornisce anche un esempio.


public static void main(String[] args)
{
Display display = new Display();
Color red = display.getSystemColor(SWT.COLOR_RED);
Color blue = display.getSystemColor(SWT.COLOR_BLUE);
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());

// set the size of the scrolled content - method 1
final ScrolledComposite sc1 = new ScrolledComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
final Composite c1 = new Composite(sc1, SWT.NONE);
sc1.setContent(c1);
c1.setBackground(red);
GridLayout layout = new GridLayout();
layout.numColumns = 4;
c1.setLayout(layout);
Button b1 = new Button(c1, SWT.PUSH);
b1.setText("first button");
c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));

// set the minimum width and height of the scrolled content - method 2
final ScrolledComposite sc2 = new ScrolledComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
sc2.setExpandHorizontal(true);
sc2.setExpandVertical(true);
final Composite c2 = new Composite(sc2, SWT.NONE);
sc2.setContent(c2);
c2.setBackground(blue);
layout = new GridLayout();
layout.numColumns = 4;
c2.setLayout(layout);
Button b2 = new Button(c2, SWT.PUSH);
b2.setText("first button");
sc2.setMinSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));

Button add = new Button(shell, SWT.PUSH);
add.setText("add children");
final int[] index = new int[]{0 };
add.addListener(SWT.Selection, new Listener()
{

public void handleEvent(Event e)
{
index[0]++;
Button button = new Button(c1, SWT.PUSH);
button.setText("button " + index[0]);
// reset size of content so children can be seen - method 1
c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
c1.layout();

button = new Button(c2, SWT.PUSH);
button.setText("button " + index[0]);
// reset the minimum width and height so children can be seen - method 2
sc2.setMinSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));
c2.layout();
}
});

shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}


L'esempio funziona, aggiungendo del contenuto (in questo caso dei bottoni) le scrollbar appaiono non appena il contenuto diventa più grande dell'area visibile.
Nella pratica però, una situazione così semplice (composite direttamente nella shell) non avviene praticamente mai, è molto più probabile che ci sia un meccanismo di scatole cinesi.. composite dentro composite dentro composite.
Se proviamo a mettere un Composite parent che contiene il nostro ScrollableComposite, già rischiamo che il meccanismo non funzioni più. Perchè?

La documentazione non dice che il parent di uno ScrollableComposite deve sempre avere un layout di tipo FillLayout. Questo è fondamentale per farlo funzionare.

Sotto un esempio più complesso del precedente:


public static void main(String[] args)
{
Display display = new Display();
Color blue = display.getSystemColor(SWT.COLOR_BLUE);
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());

FormToolkit toolkit = new FormToolkit(Display.getCurrent());

Composite container = toolkit.createComposite(shell, SWT.NONE);

// container.setLayout(new GridLayout()); NON FUNZIONA!!!!
container.setLayout(new FillLayout());

container.setLayoutData(new GridData(GridData.FILL_BOTH));

Section section = toolkit.createSection(container, ExpandableComposite.TWISTIE
| ExpandableComposite.COMPACT
| ExpandableComposite.TITLE_BAR);

section.setText("Section");
section.setLayout(new GridLayout());
section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
section.setVisible(false);

// set the minimum width and height of the scrolled content - method 2
final ScrolledComposite sc2 = new ScrolledComposite(section, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
sc2.setExpandHorizontal(true);
sc2.setExpandVertical(true);
final Composite c2 = new Composite(sc2, SWT.NONE);
sc2.setContent(c2);
c2.setBackground(blue);
GridLayout layout2 = new GridLayout();
layout2.numColumns = 4;
c2.setLayout(layout2);

for (int i = 0; i < 100; i++)
{
toolkit.createButton(c2, "button" + i, SWT.PUSH);
}

sc2.setMinSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));
section.setClient(sc2);
section.setVisible(true);
section.setExpanded(false);

shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}


Il layout di tipo Fill non consente di dimensionare a proprio piacimento lo spazio per posizionare per esempio due composite affiancati o uno sopra l'altro con altezze differenti (come invece consente il GridLayout). Ma ci sono altri meccanismi utili per fare questo come per esempio il SashForm.

venerdì 4 febbraio 2011

Eclipse RCP: aggiungere voci di menu dinamiche

Eclipse mette a disposizione un semplice meccanismo che permette di aggiungere in maniera dinamica delle voci ad un menu contestuale.

Per creare un menu è necessario dichiarare nel plugin.xml un estension point org.eclipse.ui.menus.
Supponiamo di voler aggiungere un nuovo menu alla toolbar dell'applicazione.
Aggiungiamo all'extension poin org.eclipse.ui.menus un menuContribution con

locationURI="menu:org.eclipse.ui.main.menu?after=additions"

Lo schema menu indica che il nuovo menu deve apparire sulla toolbar, mentre after=additions indica che deve apparire dopo i menu standard.

Al menuContribution aggiungiamo ora un menu, indicando id e label.


point="org.eclipse.ui.menus">
locationURI="menu:org.eclipse.ui.main.menu?after=additions">
id="it.sinossi.menu.toolbarMenu"
label="Menu Dinamico">





Aggiungiamo ora al menu un nodo di tipo dynamic e specifichiamo gli attributi id e class


point="org.eclipse.ui.menus">
locationURI="menu:org.eclipse.ui.main.menu?after=additions">
id="it.sinossi.menu.toolbarMenu"
label="Menu Dinamico">
id="it.sinossi.menu.sinossiCompoundContributionItem"
class="it.sinossi.menu.SinossiCompoundContributionItem">






La classe it.sinossi.menu.sinossiCompoundContributionItem deve estendere la classe astratta org.eclipse.ui.actions.CompoundContributionItem e implementare il metodo getContributionItems


import org.eclipse.jface.action.IContributionItem;
import org.eclipse.swt.SWT;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.CompoundContributionItem;
import org.eclipse.ui.menus.CommandContributionItem;
import org.eclipse.ui.menus.CommandContributionItemParameter;


public class SinossiCompoundContributionItem extends CompoundContributionItem
{
private static int counter = 0;

@Override
protected IContributionItem[] getContributionItems()
{
final CommandContributionItemParameter contributionParameter =
new CommandContributionItemParameter(
PlatformUI.getWorkbench().getActiveWorkbenchWindow(),
"it.sinossi.menu.sinossiCompoundContributionItem",
"it.sinossi.command.dynamicCommand",
SWT.NONE);
contributionParameter.label = "Dynamic Menu Item " + counter++;
items[i] = new CommandContributionItem(contributionParameter);
}
return new IContributionItem[] { new CommandContributionItem(contributionParameter) };
}
}


Il metodo restituisce un array di IContributionItem. Ogni elemento dell'array è un oggetto di classe org.eclipse.ui.menus.CommandContributionItem, e rappresenta una voce da aggiungere al menu. Ogni CommandContributionItem è costruito a partire da un org.eclipse.ui.menus.CommandContributionItemParameter, che contiene le caratteristiche della voce stessa.
Nel suo costruttore infatti devono essere specificati l'id dell'elemento dynamic a cui associare il CommandContributionItem e l'id del command che dovra essere eseguito quando la voce viene selezionata.
Si noti che il metodo getContributionItems viene eseguito ogni volta che viene aperto il menu, perciò la variabile counter verrà incrementata ogni volta e questo fa si che la label della voce di menu sia aggiornata dinamicamente.

Nel plugin.xml aggiungiamo l'estension point org.eclipse.ui.commands per definire il command e l'handler di default che saranno attivati alla selezione della voce


point="org.eclipse.ui.commands">
id="it.sinossi.command.dynamicCommand"
defaultHandler="it.sinossi.command.DynamicCommand"
name="Dynamic Command">


mercoledì 5 gennaio 2011

Concaterare liste con Spring

E' possibile concatenare liste di oggetti in Spring.
Con Spring 2.5 esistono due possibilità:

1) utilizzando la gerarchia di bean





Foo






Bar






Ernie
Bert





In questo modo listTree conterrà [Foo, Bar, Ernie, Bert].
Se non si vuole introdurre una gerarchia di bean, bisogna seguire un'altra strada.

2) creando una classe apposita che esegue la concatenazione


package com.company.utils.spring;
import java.util.*;
import org.springframework.beans.factory.config.ListFactoryBean;

public class ListMergerFactory extends ListFactoryBean
{
private final List listOfLists;

public ListMergerFactory(List listOfLists) throws Exception
{
this.listOfLists = listOfLists;
setSourceList(new ArrayList());
}

protected Object createInstance()
{
List listOrigin = (List) super.createInstance();
for (Iterator iter = listOfLists.iterator(); iter.hasNext();)
{
List element = (List) iter.next();
listOrigin.addAll(element);
}
return listOrigin;
}
}


E utilizzandola per creare la lista finale:






Foo






Bar















Ernie
Bert





Anche in questo modo listTree conterrà [Foo, Bar, Ernie, Bert].

lunedì 20 dicembre 2010

Securely delete files in Linux

Shred is a command line utility which can be used to securely delete files or entire file-systems.
It overwrites the file repeatedly (on my system default is 3 times, but can be specified) in order to make harder to recover the data with professional tools.
As usual for Unix's utility you can tune the program specifying parameters such as the number of overwrites.

Examples


Delete a single file:
shred -f -u -v /home/marco/file_with_secrets.txt
  • -f change permissions to allow writing if necessary
  • -u truncate and remove file after overwriting
  • -v show progress

Wipe an entire disk partition:
shred -n 10 -z -v  /dev/sdb3
  • -n # Overwrite # times instead of the default
  • -z add a final overwrite with zeros to hide shredding

Note: shred could be not so effective overwriting files in journaled file-systems (like ext3, ext4 ReiserFS, XFS, JFS) or RAID based file-systems.

Links:


shred invocation
shred - Linux man page

venerdì 10 dicembre 2010

How to mirror a remote subversion repository

When dealing with a remote repository the svnadmin command doesn't work, because it can only be used on the machine that holds the repository. But Subversion meets our need with the svnsycn command.

Svnsync works by essentially asking the Subversion server to “replay” revisions, one at a time. Neither the source nor the target repository needs to be locally accessible to machine on which svnsync is running, all the requirements are read access to the source repository and read/write access to the target/mirror repository.

Svnsync stores its bookkeeping information in special revision properties on revision 0 of the destination repository, but in order to make changes to revision properties you'll need to explicitly implement the pre-revprop-change hook, and your script must allow svnsync to set and change its special properties.

Let's see a script for local mirroring a remote svn repository:

TARGET_REPO_PATH=/tmp/svn/mirror_repo
SOURCE_REPO_PATH=https://xyz.svn.sourceforge.net/svnroot/xyz
SOURCE_REPO_USER=anonymous

svnadmin create $TARGET_REPO_PATH
echo '#!/bin/sh' > $TARGET_REPO_PATH/hooks/pre-revprop-change
chmod +x $TARGET_REPO_PATH/hooks/pre-revprop-change
svnsync init file://$TARGET_REPO_PATH $SOURCE_REPO_PATH --source-username $SOURCE_REPO_USER
svnsync sync file://$TARGET_REPO_PATH --source-username $SOURCE_REPO_USER


In line 5 we create the local target repository

In lines 6 and 7 we create the pre-revprop-change hook and make it executable

In line 8  we register in our target repository the fact that it will be a mirror of the source repository. We do this using the svnsync initialize subcommand. Our target repository will now remember that it is a mirror of the public Subversion source code repository (in Subversion 1.5, you can use svnsync to mirror only some subtree of the repository)

In line 9  with a single subcommand, we can tell svnsync to copy all the as-yet-unmirrored revisions from the source repository to the target. Svnsync performs careful bookkeeping that allows it to be safely interrupted and restarted without ruining the integrity of the mirrored data.
Do not modify a mirror repository in such a way as to cause its version history to deviate from that of the repository it mirrors. The only commits and revision property modifications that ever occur on that mirror repository should be those performed by the svnsync tool.

Whenever we want to update the mirror applying the changes from the remote source repository we just have to call the svnsync sync command as in line 9 of the example script.


Copyright note: most of this post comes from Version Control with Subversion.

See also:

Version Control with Subversion - Repository Administration - Repository Replication
Version Control with Subversion - Repository Administration - Implementing Repository Hooks
Version Control with Subversion - Repository Hooks - pre-revprop-change

venerdì 26 novembre 2010

Come abilitare lo shortcut di Eclipse "Search Occurrences in File" nell'ambiente Gnome

Come abilitare lo shortcut di Eclipse "Search Occurrences in File" nell'ambiente Gnome

Durante l'analisi del codice i comandi più utili messi a siposizione da Eclipse sono probabilemnte quelli di ricerca (sotto la voce di menù Search). Tra questi uno di quelli che uso più spesso è Search > Occurrences in File, che, come dice il nome, cerca le occorrenze dell'elemento selezionato all'interno del file aperto. La particolarità di questo comando è che, a differenza di altri comandi di ricerca come ad esempio Search > References, nella vista dei risultati della ricerca mostra proprio il contenuto delle righe in cui è presente il riferimento, permettendo di individuare in maniera molto semplice l'uso che viene fatto.

Esempio di Search References per la variabile "t":



Esempio di Search Occurrences in File per la variabile "t":




Il problema nell'usare questo comando nasce negli ambienti Gnome, in cui quello che è lo shortcut predefinito (SHIFT + CTRL + U) è associato all'inserimento dei caratteri unicode e quindi non funziona all'interno di Eclipse.
Per modificare la combinazione di tasti predefinita:

  • Aprire Window > Preferences
  • Selezionare General > Keys
  • Inserire nel filtro di ricerca la stringa occurrences
  • Selezionare la voce Shows the Occurrences in File quick menu in corrispondenza della quale la colonna "When" indica "In Windows"
  • Modificare il campo Binding inserendo la combinazione tasti desiderata
  • Cliccare su "OK" per uscere

La combinazione tasti che ho scelto nella mia configurazione è SHIFT + CTRL + Z, in quanto era libera ed è semplice da usare anche con una sola mano.

Vedi anche:

Eclipse Help - Searching the workbench
Eclipse Help - Java Search
Eclipse Help - Search Actions
Ubuntu Documentation > Community Documentation > ComposeKey > Unicode composition
Sinossi's Blog - Come inserire caratteri speciali in Linux