// ============================================================================================ // Finfo.c // ============================================================================================ // Changelog: // - 0.1 General info basic support. // - 0.1 MP3 ID3 tags support. // - 0.1 PNG graphics file support. #include // Standard input / output. #include // Standard library definitions. #include // Data types. #include // Stat types. #include // File control options. #include // Conversion types. #include // Strings library. // ============================================================================================ // Description: Special reading functions - Unix // Purpose: Read file headers bit wise. // ============================================================================================ // Read byte, 8 bits, little endian static unsigned read_le8(unsigned char *buf) { return buf[0]; } // Read 2 bytes, 16 bits, little endian static unsigned read_le16(unsigned char *buf) { return buf[0] + (unsigned)buf[1] * 0x100; } // Read 4 bytes, 32 bits, little endian static unsigned long read_le32(unsigned char *buf) { return buf[0] + (unsigned)buf[1] * 0x100 + (unsigned)buf[2] * 0x10000L + (unsigned)buf[3] * 0x1000000L; } // Read byte, 8 bits, big endian static unsigned read_be8(unsigned char *buf) { return (unsigned)buf[0]; } // Read 2 bytes, 16 bits, big endian static unsigned read_be16(unsigned char *buf) { return (unsigned)buf[0] * 0x100 + buf[1]; } // Read 4 bytes, 32 bits, big endian static unsigned long read_be32(unsigned char *buf) { return (unsigned)buf[0] * 0x1000000L + (unsigned)buf[1] * 0x10000L + (unsigned)buf[2] * 0x100 + buf[3]; } // ============================================================================================ // Description: int F_GetBasic() - Basic file info - Unix. // Purpose: Parse file to display basic stats. // -------------------------------------------------------------------------------------------- // Given: Filename. // Returned: 0/1 where success/fail. // ============================================================================================ int F_GetBasic(char* filename) { // Define vars. struct stat basic; // Structure synopsis // - st_dev - device // - st_ino - i-nodes // - st_mode - protection // - st_nlink - number of links // - st_uid - owner ID // - st_gid - group ID // - st_rdev - device type // - st_size - total size (bytes) // - st_blksize - block size // - st_blocks - blocks assigned // - st_atime - last accessed time // - st_mtime - last modified time // - st_ctime - last changed time // Look at the stats. if((lstat(filename,&basic)) < 0) { perror("lstat"); return 1; } // Display results. printf("\n Basic file info: %s",filename); printf("\n ====================================================="); printf("\n - I-node: %d \t - Total bytes: %ld", basic.st_ino , basic.st_size); printf("\n - Device: %d/%d\t - Prefered blocks: %d" , major(basic.st_dev) , minor(basic.st_dev) , basic.st_blksize); printf("\n - Dev-type: %d \t - Asigned blocks: %d" , major(basic.st_rdev) , basic.st_blocks); printf("\n - Mode: %#o \t - Owner: %d" , basic.st_mode , basic.st_uid); printf("\n - Links: %d \t - Group: %d" , basic.st_nlink , basic.st_gid); printf("\n\n"); printf(" - Latest access: %s", ctime(&basic.st_atime)); printf(" - Latest change: %s", ctime(&basic.st_mtime)); printf(" - Latest i-node: %s", ctime(&basic.st_ctime)); printf("\n"); // Exit, success. return 0; } // ============================================================================================ // Description: int F_GetGZIP() - GZIP Header - Unix. // Purpose: Parse gz file to display gzip header. // ------------------------------------------------------------------------------------------- // Given: Filename. // Returned: 0/1 where success/fail. // ============================================================================================ int F_GetGZIP(char* filename) { // Define vars. int fd; unsigned char buffer[128]; long time; // Specific XFL char* XFL[5]= { "not set", "not set", "maximun compression (-9)", "not set", "minimun compression (-1)" }; // Specific OS char* OS[255]={ "FAT filesystem (MS-DOS, OS/2, NT/Win32", "Amiga", "VMS (or OpenVMS)", "Unix - Linux", "VM/CMS", "Atari TOS", "HPFS filesystem (OS/2, NT)", "Macintosh (Mac Os)", "Z-System", "CP/M", "TOPS-20", "NTFS filesystem (NT)", "QDOS", "Acorn RISCOS", }; // Open file. if((fd=open(filename,O_RDONLY))==-1) { perror("open"); return 1; } // Jump to the required offset. lseek(fd,0,SEEK_SET); // Check if file is a valid GZIP file. if(read(fd,buffer,128) != 128) return 1; // By size if(buffer[0]!=31) return 1; // By ID1 if(buffer[1]!=139) return 1; // By ID2 // Get last modified time time = read_le32(&buffer[4]); // Display results. printf("\n Gunzip compressed (GZIP) file: %s", filename); printf("\n ====================================================="); // GZIP File Header. (No flags) printf("\n - Compression method: %ld", buffer[2]); // Compression method. - 1 bytes. printf("\n - XFL bit: %s", XFL[buffer[8]]); // XFL bit set. - 1 bytes. printf("\n - Operative system: %s", OS[buffer[9]]); // OS used with gzip. - 1 bytes. printf("\n - Last modified: %s", ctime(&time)); // Last modified. - 4 bytes. // Exit, success. close(fd); return 0; } // ============================================================================================ // Description: int F_GetMP3() - MP3 Tags - Unix. // Purpose: Parse MP3 file to display ID3 tags. // ------------------------------------------------------------------------------------------- // Given: Filename. // Returned: 0/1 where success/fail. // ============================================================================================ int F_GetMP3(char* filename) { // Define vars. int fd; unsigned char buffer[128]; // Open file. if((fd=open(filename,O_RDONLY))==-1) { perror("open"); return 1; } // Jump to the required offset. lseek(fd,-128,SEEK_END); // Check if file is a valid ID3 file. if(read(fd,buffer,128) != 128) return 1; // By size if(memcmp(&buffer[0],"TAG", 3)) return 1; // By header // Display results. printf("\n ID3 Tags found (ID3) file: %s", filename); printf("\n ====================================================="); // MP3 File ID3 Tag (128 bytes). printf("\n - Title: %s", &buffer[03]); // Title - 30 chars. printf("\n - Artist: %s", &buffer[33]); // Artist - 30 chars. printf("\n - Album: %s", &buffer[63]); // Album - 30 chars. printf("\n - Year: %s", &buffer[93]); // Year - 4 chars. printf("\n - Comment: %s", &buffer[97]); // Comment - 30 chars. printf("\n"); // Close file, success. close(fd); return 0; } // ============================================================================================ // Description: int F_GetPNG() - PNG Header. - Unix. // Purpose: Parse PNG file to display header. // ------------------------------------------------------------------------------------------- // Given: Filename. // Returned: 0/1 where success/fail. // ============================================================================================ int F_GetPNG(char* filename) { // Define vars. int fd; unsigned char buffer[30]; // Open file. if((fd=open(filename,O_RDONLY))==-1) { perror("open"); return 1; } // Jump to the required offset. lseek(fd,0,SEEK_SET); // Check if file is a valid PNG. if(read(fd,buffer,30) != 30) return 1; // By size if(memcmp(&buffer[0 ] , "\x89""PNG\r\n\x1A\n",8)) return 1; // By header if(memcmp(&buffer[12] , "IHDR",4)) return 1; // By IHDR // Display results. printf("\n Portable network graphics (PNG) file: %s", filename); printf("\n ====================================================="); // Big endian PNG header (13 bytes). printf("\n - IHDR length: %ld", read_be32(&buffer[ 8])); // IHDR - 4 bytes printf("\n - Image width: %ld pixels", read_be32(&buffer[16])); // Width - 2 bytes printf("\n - Image height: %ld pixels", read_be32(&buffer[20])); // Height - 2 bytes printf("\n - Bit depth: %ld", read_be8(&buffer[24])); // Depth - 1 byte printf("\n - Color type: %ld", read_be8(&buffer[25])); // Type - 1 byte printf("\n - Compression: %ld", read_be8(&buffer[26])); // Comp - 1 byte printf("\n - Filter scheme: %ld", read_be8(&buffer[27])); // Filter - 1 byte printf("\n - Interlace type: %ld", read_be8(&buffer[28])); // Interlace - 1 byte printf("\n"); // Table info. printf("\n Allowed color types: Allowed bit depths: "); printf("\n - 0 : Grayscale - 1,2,4,8,16: Each pixel is grayscale. "); printf("\n - 2 : RGB - 8,16: Each pixel is a RGB triplet. "); printf("\n - 3 : Palette mode - 1,2,4,8: Each pixel is paletted. (PLT) "); printf("\n - 4 : Grayscale + Alpha channel - 8,16: Each pixel is followed by mask. "); printf("\n - 6 : RGB + Alpha channel - 8,16: Each pixel is followed by mask "); printf("\n"); printf("\n Allowed filter schemes: Allowed interlace types: "); printf("\n - 0 : Adaptive filtering - 0 : No interlace "); printf("\n - 1 : Unsupported - 1 : Adam 7 interlace "); printf("\n"); // Close file and exit, success. close(fd); return 0; } // ============================================================================================ // Description: int Main() - Main program entry. // Purpose: Parse command line parameters and call file info functions. // ------------------------------------------------------------------------------------------- // Given: Parameters. // Returned: 0/1 where success/fail. // ============================================================================================ int main(int argc, char *argv[] ) { // Look though parameters. // Display usage. if(argc<2) { printf("Usage: finfo file...\n"); printf("Displays all avaiable file information for supported file-types.\n\n"); printf("Examples:\n"); printf("finfo *.mp3 \t Get information on all MP3 files in actual directory.\n\n"); return 1; } // Declare vars. int x; // Look for the current file info on all files. for(x=1;x