#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define FIBMAP _IO(0x00,1) /* accesso bmap */ #define FIGETBSZ _IO(0x00,2) /* ottiene la dimensione del blocco usata per bmap */ #define EXT4_EXTENTS_FL 0x00080000 /* Inode usa extents */ #define EXT3_IOC_GETFLAGS _IOR('f', 1, long) #define EXT2_DIRECT 12 // PROTOTIPI typedef struct d { char *path; char *tipo; int major; int minor; int inode; char *permessi; int fs; char *utente; char *gruppo; int num_blocchi; long int dim_blocco; long int dim_file; unsigned long primo_blocco; unsigned long ultimo_blocco; int n_discont; char *link; }dato; dato info(char *path); void printInfo(dato d); char* permessi(int mode); unsigned long get_bmap(int fd, unsigned long block); int stato_framm(char* argv,int *n_blocchi,unsigned long *ultimo_blocco,unsigned long *primo_blocco,int *discontinuita,struct stat sb,long int *dim_file); // FUNZIONI void printInfo(dato d){ fprintf (stdout,"Il file *%s* è di tipo: ",d.path); fprintf (stdout,"%s\n",d.tipo); fprintf (stdout,"L'id dell'inode è: %d\n",d.inode); fprintf (stdout,"I permessi di questo file sono: %s \n",d.permessi); if(d.fs == 61267) fprintf(stdout,"Il file system è di tipo: EXT2/EXT3\n"); else if (d.fs == 19780) fprintf(stdout,"Il file system è di tipo: MSDOS\n"); else if (d.fs == 1702057286) fprintf(stdout,"Il file system è di tipo: NTFS\n"); else fprintf(stdout,"Il file system è di tipo: %d\n",d.fs); fprintf(stdout,"La dimensione del blocco è: %ld\n",d.dim_blocco); fprintf(stdout,"Utente: %s\tGruppo: %s\n",d.utente,d.gruppo); if(!strcmp(d.tipo,"Link simbolico")) fprintf(stdout,"Il link punta a: %s\n",d.link); else if(!strcmp(d.tipo,"File regolare")){ fprintf(stdout,"La dimensione del file %s è %ld byte che corrispondono a %d blocchi\n",d.path,d.dim_file,d.num_blocchi); fprintf(stdout,"Il primo blocco fisico è: %lu\n",d.primo_blocco); fprintf(stdout,"L'ultimo blocco fisico è: %lu\n",d.ultimo_blocco); fprintf(stdout,"Il file è frammentato in %d parti\n",d.n_discont); } else if((!strcmp(d.tipo,"Device di carattere")) || (!strcmp(d.tipo,"Device di carattere"))){ fprintf(stdout,"Il major number è: %d\n",d.major); fprintf(stdout,"Il minor number è: %d\n",d.minor); } } int stato_framm(char* argv,int *n_blocchi,unsigned long *ultimo_blocco,unsigned long *primo_blocco,int *discontinuita,struct stat sb,long int *dim_file){ int i,discont=0,numblocks=0,fd,bs,flag,is_ext2=1; long ind_block; /* Blocks per indirect block */ unsigned long block=0,last_block=0; fd = open(argv, O_RDONLY); if (fd < 0) { fprintf(stderr,"Impossibile aprire il file:\" %s \"\n",argv); return -1; } if (ioctl(fd, FIGETBSZ, &bs) < 0) { /* FIGETBSZ takes an int */ fprintf(stderr,"Errore ioctl\n"); close(fd); return -1; } if (ioctl(fd, EXT3_IOC_GETFLAGS, &flag) < 0) flag = 0; if (flag & EXT4_EXTENTS_FL) { printf("Il file è memorizzato nel formato extent\n"); is_ext2 = 0; } ind_block = bs / 4; numblocks = (sb.st_size + (bs-1)) / bs; //printf("La dimensione del file %s è %lld byte che corrispondono a %d blocchi\n", argv, (long long) sb.st_size, numblocks); //printf("Il primo blocco fisico è: %lu\nL'ultimo blocco fisico è: %lu\n",get_bmap(fd, 0), get_bmap(fd, numblocks - 1)); *primo_blocco=get_bmap(fd,0); *ultimo_blocco=get_bmap(fd, numblocks-1); *dim_file=(long long) sb.st_size; for (i=0; i < numblocks; i++) { if (is_ext2 && last_block) { if (((i-EXT2_DIRECT) % ind_block) == 0) last_block++; if (((i-EXT2_DIRECT-ind_block) % (ind_block*ind_block)) == 0) last_block++; if (((i-EXT2_DIRECT-ind_block-ind_block*ind_block) % (ind_block*ind_block*ind_block)) == 0) last_block++; } block = get_bmap(fd, i); if (block == 0) continue; if (last_block && (block != last_block +1) ) { //printf("Discontinuità rilevata: il blocco logico %d è memorizzato nel blocco fisico %lu invece di essere nel blocco fisico %lu\n",i, block, last_block); discont++; } last_block = block; } *discontinuita = discont; *n_blocchi = numblocks; return 1; } char * permessi(int mode){ int risultato = mode & 0x1FF; char *stringa= malloc(sizeof(char*)); //char *stringa; if (risultato & 0x100) { strcat(stringa,"r"); } else { strcat(stringa,"-"); } if (risultato & 0x80) { strcat(stringa,"w"); } else { strcat(stringa,"-"); } if (risultato & 0x40) { strcat(stringa,"x"); } else { strcat(stringa,"-"); } if (risultato & 0x20) { strcat(stringa,"r"); } else { strcat(stringa,"-"); } if (risultato & 0x10) { strcat(stringa,"w"); } else { strcat(stringa,"-"); } if (risultato & 0x08) { strcat(stringa,"x"); } else { strcat(stringa,"-"); } if (risultato & 0x04) { strcat(stringa,"r"); } else { strcat(stringa,"-"); } if (risultato & 0x02) { strcat(stringa,"w"); } else { strcat(stringa,"-"); } if (risultato & 0x01) { strcat(stringa,"x"); } else { strcat(stringa,"-"); } return stringa; } unsigned long get_bmap(int fd, unsigned long block) { int ret; unsigned int b; b = block; ret = ioctl(fd, FIBMAP, &b); /* FIBMAP richiede un puntatore ad intero */ if (ret < 0) { if (errno == EPERM) { fprintf(stderr, "Per utilizzare questo programma è necessaro essere root\n"); exit(1); } } return b; }