Progetto1 – Lab. di Sistemi Operativi – Find.c

#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))));
}

Progetto1 – Lab. di Sistemi Operativi – Informazioni Utili

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.

Windows7 da Inglese a Italiano

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!

Come modificare la lingua in windows 7 professional in italiano:
  1. Per prima cosa bisogna procurarsi il DVD del language pack o una sua immagine ISO montabile su un drive virtuale o i file della lingua desiderata. Inoltre è possibile estrarre dall’ISO la cartella it-it (corrispondente alla lingua italiana) senza dover per forza virtualizzare il disco.
  2. Aprire il Prompt dei Comandi in modalità amministratore (fare tastro destro sull’icona e sceglie “run as administrator”).
  3. Scrivere le seguente righe sul prompt: DISM /Online /Add-Package /PackagePath: “percorso file lingua” come ad esempio: DISM /online /add-package /packagepath:C:\langpacks\it-it\lp.cab . Aspettare che finisca di caricare ed installare i file di lingua (ci potrebbero volere anche 10 min).
  4. Scrivere: bcdedit /set {current} locale it-it con al posto di it-it (che sta per italiano) la vostra lingua, per impostare la lingua del sistema.
  5. Scrivere exit per uscire dal prompt.
  6. Andare su start e scrivere regedit sulla barra di ricerca per aprire il registro di sistema.
  7. Andare alla chiave HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\MUI\ UILanguages e cancellare la voce relativa alla lingua inglese en-US.
  8. Chiudere il registro e riavviare il pc per gustarvi Windows 7 Professional nella vostra lingua preferita.
Questa è una guida a solo scopo informativo e non mi riterrò responsabile per qualsiasi danno da voi prodotto al PC.

[via]

Progetto1 – Lab. di Sistemi Operativi

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 del
comando 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 special
c character special
d directory
f regular file
l symbolic link
p FIFO
s 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

Nei prossimi giorni, a distanza di due settimane da ogni progetto, pubblicherò il rispettivo codice. Sarà una base su cui partire e sicuramente ampliarla aggiungendo ulteriori controlli sull’elaborato, quindi NON COPIATE. Non mi prendo nessuna responsabilità se il prof. vi sgama, poichè questo materiale è stato pubblicato solo a scopo informativo.

I 20 BEST FREE games for your iPhone

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!

Commodore 64 (Link AppStore)

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]

MySQL da Prompt dei comandi

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? :)