/* stat.c  -- It prints out information about file whose path is passed 
 *            as parameter.
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>

// Using same rules as used by ls -l
// it returns as a string the modes of a.
char * setmode(int a){
  static char mode[] = "----------";
  mode[0] = (a & S_IFREG) ? '-'
    :((a & S_IFDIR)? 'd'
      :((a & S_IFBLK)?'b'
	:((a & S_IFCHR)?'c'
	  :((a & S_IFIFO)?'p'
	    :((a & S_IFSOCK)?'s'
	      :((a & S_IFLNK)?'l':' '))))));
  mode[1] = (a & S_IRUSR) ? 'r' : '-';
  mode[2] = (a & S_IWUSR) ? 'w' : '-';
  mode[3] = (a & S_ISUID) ? ((a & S_IXUSR)?'s':'S'):((a & S_IXUSR)?'x':'-');
  mode[4] = (a & S_IRGRP) ? 'r' : '-';
  mode[5] = (a & S_IWGRP) ? 'w' : '-';
  mode[6] = (a & S_ISGID) ? ((a & S_IXGRP)?'s':'S'):((a & S_IXGRP)?'x':'-');
  mode[7] = (a & S_IROTH) ? 'r' : '-';
  mode[8] = (a & S_IWOTH) ? 'w' : '-';
  mode[9] = (a & S_ISVTX) ? ((a & S_IXOTH)?'t':'T'):((a & S_IXOTH)?'x':'-');
  return ((char *)&mode);
}

int main (int argc, char *argv[]) {
  static struct stat ds;

  if (argc < 2) {
     printf("Usage: %s filename\n", argv[0]);
     exit(1);}
  if (stat(argv[1], &ds) < 0) {
     perror("stat");
     exit(1);}
  printf("Information on %s:\n", argv[1]);
  printf("\tDevice: %u\n", (unsigned int)ds.st_dev);
  printf("\tFile Serial Number: %ld\n", ds.st_ino);
  printf("\tFile Mode: %s\n", setmode(ds.st_mode));
  printf("\tNumber of Links: %d\n", ds.st_nlink);
  printf("\tUser Id: %d\n", ds.st_uid);
  printf("\tGroup Id: %d\n", ds.st_gid);
  printf("\tMajor Id of device: %d\n", 
	(unsigned int)(((ds.st_rdev)>>20)&07777));
  printf("\tMinor Id of device: %d\n", 
	(unsigned int)((ds.st_rdev)&03777777));
  printf("\tFile size in bytes: %d\n", (unsigned int)ds.st_size);
  printf("\tTime of last access: %s", ctime(&ds.st_atime));
  printf("\tTime of last modification: %s", ctime(&ds.st_mtime));
  printf("\tTime of last file status change: %s", ctime(&ds.st_ctime));
  printf("\tSize of block in file: %d\n", 
	(unsigned int)ds.st_blksize);
  printf("\tBlocks allocated for file: %d\n", 
	(unsigned int)ds.st_blocks);
  /*
  printf("\tUser defined flags of file: %d\n", ds.st_flags);
  printf("\tFile generation number: %d\n", ds.st_gen);
   */
  return 0;
}

