rendered paste body// ============================================================================================
// Finfo.c
// ============================================================================================
// Changelog:
// - 0.1 General info basic support.
// - 0.1 MP3 ID3 tags support.
// - 0.1 PNG graphics file support.
#include <stdio.h> // Standard input / output.
#include <stdlib.h> // Standard library definitions.
#include <sys/types.h> // Data types.
#include <sys/stat.h> // Stat types.
#include <fcntl.h> // File control options.
#include <ctype.h> // Conversion types.
#include <string.h> // 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<argc;x++) {
F_GetBasic(argv[x]);
F_GetGZIP(argv[x]);
F_GetMP3(argv[x]);
F_GetPNG(argv[x]);
printf("\nNo further info.\n");
}
// Exit, success.
return 0;
}
// ============================================================================================
// EOF.
// ============================================================================================