#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
struct stat buf;
struct dirent *direntp;
struct ver {
char command[10];
union {
int vint;
unsigned long int vuns;
char vvet[100];
char vcha;
} value;
} ver[8];
int ac=0,button=1,bkac;
int Oct2Dec(int);
double poww(int, int);
char *uid_to_name(uid_t);
char *gid_to_name(gid_t);
//////////////////////////////////////////////////
// Funzione utilizzata per i seguenti comandi:
// ./find -f pathname espressione
//////////////////////////////////////////////////
void do_find(char dirname[])
{
//Apro la cartella
DIR *dir = opendir(dirname);
//Provo a leggere al suo interno
while((direntp=readdir(dir))!=NULL)
{
//Effettuo una "pulizia" del futuro stampato
if((strcmp((direntp->d_name),".")!=0)
&&(strcmp((direntp->d_name),"..")!=0))
{
//Creo il pathname
char mio[(strlen(dirname)+100)];
strcpy(mio,dirname);
strcat(mio,"/");
strcat(mio,direntp->d_name);
//Ripristino il numero delle opzioni
ac=bkac;
//button mi permette di verificare se il file o la directory attuale
// verificano tutte le opzioni; infatti, per ogni opzione, button
// viene moltiplicato per 1 se è verificata, per 0 se non è
// verificata. Andando a zero, rimarrà tale anche se le altre
// opzioni sono verificate
button=1;
//verifico ogni opzione
while(ac!=0)
{
//Nel caso in cui: -amin o -perm
if((strcmp(ver[(ac-1)].command,"-amin")==0)
||(strcmp(ver[(ac-1)].command,"-perm")==0))
{
//stat() è una chiamata di sistema Unix che restituisce
// dati utili su un file
if(stat((mio),&buf)==0)
{
if(strcmp(ver[(ac-1)].command,"-amin")==0)
{
time_t dtime;
//Trovo quanto è passato dall'ultimo accesso,
//e aggiungo 1 per una correzione
dtime=(int)((time(NULL)-(buf.st_atime))/60)+1;
if(ver[(ac-1)].value.vint==(int)dtime) button=button*1;
else button=button*0;
}
if(strcmp(ver[(ac-1)].command,"-perm")==0)
{
if(Oct2Dec(ver[(ac-1)].value.vint)==(buf.st_mode)) button=button*1;
else button=button*0;
}
}
}
//Nel caso in cui -links
else if(strcmp(ver[(ac-1)].command,"-links")==0)
{
//Qui è stato usato lstat poichè, nel caso di un symbolic link,
//vogliamo ottenere le informazioni
//sul link, e non sul file a cui è legato
if(lstat((mio),&buf)==0)
{
if(ver[(ac-1)].value.vuns==(unsigned long int)(buf.st_nlink))
button=button*1;
else button=button*0;
}
}
//Nel caso in cui -user o -group
else if((strcmp(ver[(ac-1)].command,"-user")==0)
||(strcmp(ver[(ac-1)].command,"-group")==0))
{
if(stat((mio),&buf)==0)
{
if(strcmp(ver[(ac-1)].command,"-user")==0)
{
char* auid;
auid=uid_to_name(buf.st_uid);
if(strcmp(auid,ver[(ac-1)].value.vvet)==0) button=button*1;
else button=button*0;
}
if(strcmp(ver[(ac-1)].command,"-group")==0)
{
char* guid;
guid=gid_to_name(buf.st_uid);
if(strcmp(guid,ver[(ac-1)].value.vvet)==0) button=button*1;
else button=button*0;
}
}
}
//Nel caso in cui -name
else if(strcmp(ver[(ac-1)].command,"-name")==0)
{
if(strcmp(direntp->d_name,ver[(ac-1)].value.vvet)==0)
button=button*1;
else button=button*0;
}
//Nel caso in cui -inum
else if(strcmp(ver[(ac-1)].command,"-inum")==0)
{
if(stat((mio),&buf)==0)
{
if(ver[(ac-1)].value.vuns==(unsigned long int)(buf.st_ino))
button=button*1;
else button=button*0;
}
}
//Nel caso in cui -type
else if(strcmp(ver[(ac-1)].command,"-type")==0)
{
char ttype=ver[(ac-1)].value.vcha;
//Verifico di che tipo è
if(((ttype=='b')&&((direntp->d_type)==DT_BLK))
||((ttype=='c')&&((direntp->d_type)==DT_CHR))
||((ttype=='d')&&((direntp->d_type)==DT_DIR))
||((ttype=='f')&&((direntp->d_type)==DT_REG))
||((ttype=='p')&&((direntp->d_type)==DT_FIFO))
||((ttype=='s')&&((direntp->d_type)==DT_SOCK))
||((ttype=='l')&&((direntp->d_type)==DT_LNK))) button=button*1;
else button=button*0;
}
//Passo alla prossima opzione
ac--;
}
//Se tutto è verificato, stampo
if(button) printf("%s\n", mio);
//se trovo una directory, entro. Il file invece ha valore 8.
if((direntp->d_type)==DT_DIR) do_find(mio);
}
}
//chiudo la directory
closedir(dir);
}
////////////////////////////////////////////////
// FUNZIONE MAIN
////////////////////////////////////////////////
int main(int argc, char *argv[])
{
if((argc==1)||(strcmp(argv[1],"-f")!=0)||((argc%2)==0))
{
printf("find: COMMAND ERROR\n");
}
//Comando: ./find -f pathname espressione
else
{
ac=(argc-3)/2;
bkac=ac;
int acont=3;
while(ac!=0)
{
//Salvo il comando attuale
strcpy(ver[(ac-1)].command,argv[acont]);
//Incremento per andare a selezionare il parametro
acont++;
//Verifico di quale si tratta e salvo il valore relativo
if(strcmp(ver[(ac-1)].command,"-amin")==0)
{
ver[(ac-1)].value.vint=atoi(argv[acont]);
}
else if(strcmp(ver[(ac-1)].command,"-perm")==0)
{
ver[(ac-1)].value.vint=atoi(argv[acont]);
}
else if(strcmp(ver[(ac-1)].command,"-name")==0)
{
strcpy(ver[(ac-1)].value.vvet,argv[acont]);
}
else if(strcmp(ver[(ac-1)].command,"-user")==0)
{
strcpy(ver[(ac-1)].value.vvet,argv[acont]);
}
else if(strcmp(ver[(ac-1)].command,"-group")==0)
{
strcpy(ver[(ac-1)].value.vvet,argv[acont]);
}
else if(strcmp(ver[(ac-1)].command,"-inum")==0)
{
ver[(ac-1)].value.vuns=atoi(argv[acont]);
}
else if(strcmp(ver[(ac-1)].command,"-links")==0)
{
ver[(ac-1)].value.vuns=atoi(argv[acont]);
}
else if(strcmp(ver[(ac-1)].command,"-type")==0)
{
ver[(ac-1)].value.vcha=argv[acont][0];
}
else
{
//Nel caso in cui l'espressione contiene un opzione non valida
printf("find: COMMAND ERROR\n");
exit(1);
}
acont++;
ac--;
}
//Effettuo un backup del numero dei comandi, utilizzato
//poi nella funzione
ac=bkac;
do_find(argv[2]);
}
return 1;
}
///////////////////////////////////////////////////////
// Funzione che restituisce il nome dell'utente dall'ID
///////////////////////////////////////////////////////
#include <pwd.h>
char *uid_to_name(uid_t uid)
{
struct passwd *getpwuid(),*pw_ptr;
static char numstr[10];
if( (pw_ptr = getpwuid(uid)) == NULL ){
sprintf(numstr,"%d",uid);
return numstr;
}
else
return pw_ptr->pw_name;
}
//////////////////////////////////////////////////////
// Funzione che restituisce il nome del gruppo dall'ID
//////////////////////////////////////////////////////
#include <grp.h>
char *gid_to_name(gid_t gid)
{
struct group *getgrgid(),*grp_ptr;
static char numstr[10];
if( (grp_ptr = getgrgid(gid)) == NULL ) {
sprintf(numstr,"%d",gid);
return numstr;
}
else
return grp_ptr->gr_name;
}
//////////////////////////////////////////////////////
// Funzione che converte un ottale in decimale
//////////////////////////////////////////////////////
int Oct2Dec(int oct)
{
int n,r,i;
n=oct;
oct=0;
for(i=0;n!=0;i++)
{
r=n%10;
oct=oct+r*poww(8,i);
n=n/10;
}
return oct;
}
//////////////////////////////////////////////////////
// Funzione per la potenza
//////////////////////////////////////////////////////
double poww(int b, int e)
{
if(e==0) return 1;
else return(b*(poww(b,(e-1))));
}
Lo sviluppo del progetto è avvenuto in due fasi distinte: durante la prima fase abbiamo cercato di comprendere la funzionalità reale di ogni comando, implementando ognuno singolarmente. Nella seconda fase, invece, abbiamo accorpato tutte le funzioni che prima erano separate, in un’unica funzione, permettendo inoltre la possibilità di più opzioni contemporaneamente.
Il limite del numero di tali opzioni eseguibili nel comando contemporaneamente è stato fissato arbitrariamente a 8, poiché è il numero di opzioni disponibili. Abbiamo escluso da questo conteggio l’opzione “-f pathname” poiché essa è obbligatoria. Infatti l’assenza di tale opzione genererà un COMMAND ERROR.
Tale errore verrà anche segnalato qualora mancasse un parametro di una qualsiasi opzione (controllo reso possibile verificando se il valore di argc NON sia un numero pari.)
Ad esempio, se diamo il seguente comando, in cui tutti i parametri sono presenti:
./find -f . -name prova -amin 1
il valore di argc sarà un numero dispari (argc=7). Qualora i parametri dimenticati fossero in numero pari (ad esempio 2), una delle opzioni verrà presa come parametro, comportando ovvi errori.
Abbiamo anche imposto, come suggerito dal Professore, che la prima opzione debba essere appunto quella relativa al pathname (-f pathname), che verrà poi seguita dalle altre eventuali opzioni.
Sempre nel main abbiamo inserito questa riga di codice
ac=(argc-3)/2;
che ci permette di vedere quante opzioni sono state indicate.
Per quanto riguarda la gestione delle opzioni si è adottato un vettore di record, dove l’opzione vera e propria viene salvata all’interno di ver[n].command; mentre il parametro viene salvato nel successivo campo (realizzato con un union, poiché il parametro può essere solo di un tipo/valore alla volta).
Entrando invece in merito della funzione principale del progetto (do_find), abbiamo deciso di passare per parametro solamente il pathname della directory corrente (che via via diverrà directory padre, quando, tramite la ricorsione, entreremo nelle sottocartelle…).
La variabile button mi permette di verificare se il file o la directory attuale verificano tutte le opzioni imposte: infatti, per ogni opzione, button viene moltiplicato per 1 se essa è verificata, per 0 invece se non è verificata. Tale variabile, andando a zero, rimarrà tale anche se le altre opzioni sono successivamente verificate.
Ma ora vediamo ogni singolo punto della funzione:
-amin n: dopo aver creato la variabile dtime di tipo time_t, andiamo ad effettuare una differenza tra time(NULL), che contiene l’istante di tempo attuale, e buf.st_atime, che contiene l’istante dell’ultimo accesso al file o directory analizzata. Dividendo tale valore per 60, otteniamo il corrispettivo valore in minuti. L’aggiunta del +1 finale mi permette una “approssimazione” (per essere sincronizzati come il comando da shell).
-inum n: verifichiamo semplicemente che il valore di inode del file o directory attuale sia corrispondente al parametro indicato nel comando.
-name nome: verifichiamo che il nome del file o della directory attuale sia pari al nome indicato nel comando.
-perm octal_number: siccome il valore corrispondente ai permessi è salvato in memoria in decimale, prima di effettuare il confronto eseguiamo la conversione da ottale a decimale del parametro indicato nel comando.
-user nome e -group nome: verifichiamo che il nome del proprietario (oppure il nome del gruppo) del file o della directory corrente sia corrispondente al nome indicato nel comando. Ciò è possibile utilizzando le due funzioni
char *uid_to_name(uid_t)
e
char *gid_to_name(gid_t)
contenute rispettivamente nelle librerie pwd.h e grp.h, che ricavano appunto il proprietario del relativo file o directory analizzata.
-type t: tramite questa serie di controlli
(((ttype==’b')&&((direntp->d_type)==DT_BLK))||((ttype==’c')&&((direntp->d_type)==DT_CHR))||((ttype==’d')&&((direntp->d_type)==DT_DIR))||((ttype==’f')&&((direntp->d_type)==DT_REG))||((ttype==’p')&&((direntp->d_type)==DT_FIFO))||((ttype==’s’)&&((direntp->d_type)==DT_SOCK))||((ttype==’l')&&((direntp->d_type)==DT_LNK)))
riesco immediatamente ad individuare se il tipo del file o della directory corrisponde a quello ricercato (e quindi corrisponde al parametro presente nel comando).
-links n: in questa funzione, a differenza delle altre, è stata usata lstat(), poichè nel caso di un symbolic link, era necessario ottenere le informazioni sul file link, e non sul file a cui è legato. E questo ci viene concesso appunto dalla funzione lstat(). Se usavamo invece la funzione stat(), ottenevamo le informazioni riguardante il file che era referenziato. Dopodichè verifichiamo la corrispondenza con il parametro del comando.
Avete installato anche voi l’edizione di Windows7 sul vostro PC, ma vi siete accorti che è in INGLESE e non sapete come fare? Nessun problema!
Vi basterà infatti seguire questi pochi passi per avere il vostro sistema operativo del cuore nella vostra lingua preferita!
[via]
Nel terzo trimestre dell’anno 2010, il corso di Laboratorio di Sistemi Operativi è iniziato con un progetto non troppo difficile, ma abbastanza impegnativo. Ecco a voi la consegna:
Progetto 1 – implementare una versione di find
Il progetto propone allo studente di esaminare l’implementazione delcomando find implementando le seguenti espressioni:-amin n differenza in minuti tra last access time e the time quando find iniziato;-inum n numero di inode pari ad n;-name nome nome del file pari a nome;-perm octal_number permessi pari al valore ottale;-user nome proprietario con nome nome;-group nome gruppo con nome nome;-type t [b block specialc character speciald directoryf regular filel symbolic linkp FIFOs socket ] tipo di file di tipo t;-links n file ha n links;-f pathname pathname da cui iniziare la ricerca.La sintassi è la seguente:find –f pathname espressione
Di solito nessuno da niente per niente ma nel caso dell’AppStore è, alle volte, possibile contravvenire a questo detto. Se la maggior parte dei giochi non arriva a costare nemmeno il prezzo di un caffè, esiste una immensa fetta di applicazioni gratuite. Ecco allora, puntuale come un orologio svizzero, una classifica stilata da PocketGamer, contenente i 20 migliori titoli gratuiti scaricabili su AppStore.
La classifica in realtà si divide in due grossi tronconi. La prima parte è riservata a quelle applicazioni solo all’apparenza gratuite, dove occorre pagare per acquistare contenuti aggiuntivi o simili. La seconda metà è, invece, destinata ai giochi totalmente “free”, per i quali non occorrerà sborsare un euro. Ecco i consigli per gli acquisti, o meglio, i consigli per risparmiare divertendovi!
La prima menzione, seppur al ventesimo posto ( decimo se si considerano le due classifiche come separate!), spetta a Commodore 64, applicazione che permette di rivivere i giorni in cui i giochi passavano dai vecchi e cari nastri. In bundle ci sono 7 giochi gratuiti ed altri possono essere scaricati da itunes per soli 0,79€.
ZombieFarm (Link AppStore)
Se fate parte di quella schiera di utenti che ama alla follia Farmville, ma vorreste la vostra fattoria piena di Zombie, allora ZombieFarm potrebbe fare al caso vostro.
TapTap Revenge 3 (Link AppStore)
TapTap Revenge 3 non poteva sicuramente mancare in questa particolare classifica. Per gli amanti dei rhythm games è sicuramente un acquisto obbligato. Certo, il gioco non è in tutto e per tutto gratuito, ma se volete fare soltanto una prova, potete tranquillamente scaricare il programma base e godervi qualche hit più o meno famosa.
MafiaWars (Link AppStore)
Se la vita di campagna non fa per voi e ZombieFarm, o Farmville, non sono esattamente i titoli che preferite giocare, allora potrete gettarvi su Mafia Wars, un gioco strategico in cui occorrerà acquisire armi, proprietà e controllo di molti territori.
Pocket Legend (Link AppStore)
Un simpatico MMO dove il giocatore potrà prendere parte a tante quest e personalizzare come meglio crede il proprio personaggio.
We Rule (Link AppStore)
Il gioco che più appassiona gli utenti dei farmville-game-style, tanto da aver buttato giù i server di ngmoco nei primi giorni dopo il rilascio.
Tap Fish (Link AppStore)
Un semplice acquario sul vostro melafonino. Se avete soldi da spendere esistono davvero tanti extra da poter acquistare.
The God Father’s Games (Link AppStore)
Il team in questione offre alcuni giochi completamente gratuiti: Race or Die, iMob, Jet Fighters, iKnights, iVampires, e Girl Wars.

IMO: The World of Magic (Link AppStore)
IMO è un MMORPG con grafica pixel art davvero bella. Il gioco ha tre classi, funzioni di social networking, e un’arena con possibilità di partita 1 vs 1.
VH1 Classic Presents: Intellivision (Link AppStore)
Chiudiamo questa prima parte di classifica proprio come l’abbiamo iniziata, ossia con un emulatore di vecchie glorie. Questa volta, si tratta dell’ intellivision, scaricabile gratuitamente da AppStore.
Passando in rassegna i giochi totalmente gratuiti, che non necessitano di alcuna spesa, abbiamo:
FallDown! (Link AppStore)
FallDown! è un semplice giochino passatempo dove occorrerà guidare una palla sfruttando l’accelerometro del dispositivo ed inclinando a destra o a sinistra il dispositivo. Il titolo è gratuito ma se volete sbarazzarvi della pubblicità potete sempre sborsare 0,79€.
Depict (Link AppStore)
Il titolo in questione è un divertente multiplayer game dove occorrerà disegnare delle parole e farle indovinare ai propri amici di gioco.
Trundle (Link AppStore)
Trundle è uno splendido adventure-puzzle-game dove occorrerà fare i conti con la fisica, spostando blocchi, compiendo salti al limite dell’impossibile o attivando svariati macchinari. Il gioco base è molto lungo e piacevole ma se volete spendere qualche soldo in più potete anche acquistare un livello aggiuntivo.
MobileRice (Link AppStore)
10 chicchi di riso per le persone bisognose ad ogni risposta esatta. Questo il motivo della presenza di questa app nella classifica di cui stiamo trattando.
Solitaire (Link AppStore)
Un evergreen su iPhone. Da giocare in qualsiasi momento della giornata. Un classico solitario non si rifiuta mai!
A Quest of Knights Onrush (Link AppStore)
Se amate i tower defense questo titolo di Chillingo farà sicuramente al caso vostro. Iniziate a farvi strada in mezzo a orde di nemici.
Real Racing GTI (Link AppStore)
Firemint, in collaborazione con Volkswagen ha creato un gioco di auto davvero ben fatto. La versione base, quindi gratuita è già molto appagante.

Spider: Hornet Smash (Link AppStore)
Orde di calabroni invadono il nostro iPhone. Scacciatene quanti più potete.
Paper Toss (Link AppStore)
Se vi annoiate a lavoro e non volete contare le pecore allora paper toss fa al caso vostro. Appallottola carte e gettale nel cestino della spazzatura, attraverso 6 diversi livelli di gioco.
Truffic Rush (Link AppStore)
Il traffico si farà sempre più intenso nelle strade di Traffic Ruch di Donut Games. Sfiora le auto e falle sfrecciare a tutta velocità, ma attenti a non tamponare nessuno!
[via]
Quante volte sarà capitato anche a voi di dover utilizzare MySQL da riga di comando, ma non voler passare al terminale di Ubuntu rimanendo sotto il nostro amatissimo Windows? Ebbene, i vostri incubi sono finiti.
Ecco una breve e semplice guida per utilizzare MySQL dal Prompt dei comandi di Windows.
Prima di tutto abbiamo bisogno di Apache e MySQL installati sulla macchina. Niente paura. Due click e il gioco è fatto! Infatti corre in nostro aiuto EasyPHP, un comodissimo strumento FREE per sviluppo, che una volta avviato, fa partire il motore Apache e MySQL.
Tale software, è possibile scaricarlo da qui: download.
Dopo averlo installato, eseguiamo questi semplici passi:
1. Apri il prompt dei comandi dal menu start.
2. Lanciare EasyPhp
3. Digitare dal Prompt dei comandi: “cd C:\Program Files\EasyPHP5.3.0\mysql\bin”
4. Digitare: “mysql.exe -u root -p”
5. Digitare la password se ne abbiamo impostata una, altrimenti premere invio.
Facile no?