#!mkcmd # mkcmd for stat util from '' from '' from '' from '' from '' from '' from '' from '' require "std_help.m" "std_version.m" basename "stat" "" %i static char rcsid[] = "$Id: stat.m,v 2.11 2012/11/08 15:07:26 ksb Exp $"; #if defined(SYSV) || defined(MASSCOMP) #include #endif /* SYSV */ /* more evolved systems have a inode allocation time (birthtime) */ #if !defined(HAVE_BIRTHTIME) #define HAVE_BIRTHTIME (defined(FREEBSD) && (HOSTOS>=70000)) #endif %% %c #define FAIL -1 /* Failure return code from call */ #define OKAY 0 /* Success return code from call */ struct stat Sbuf; /* for return values from stat() call */ void exit(); /* Terminate the program */ char *ctime(); /* Time conversion */ struct passwd *getpwuid(); /* User entry */ struct passwd *pwent; /* User structure */ struct group *getgrgid(); /* Group entry */ struct group *grent; /* Group structure */ char acMode[16]; /* File protection mode "drwxrwxrwx\000" */ #if defined(S_IFLNK) #define LBUFSIZ 1024 /* Length for symbolic link translation buffer */ char Lbuf[LBUFSIZ]; /* Symbolic link translation buffer */ #endif #ifdef SINCE void tsince(time_sec) time_t time_sec; { time_t time_buf; time_t d_since; /* days elapsed since time */ time_t h_since; /* hours elapsed since time */ time_t m_since; /* minutes elapsed since time */ time_t s_since; /* seconds elapsed since time */ char *backward; /* "-" if future time, else "" */ (void) time(&time_buf); if (time_sec > time_buf) { time_t temp; temp = time_sec; time_sec = time_buf; time_buf = temp; backward = "-"; } else { backward = ""; } s_since = time_buf - time_sec; d_since = s_since / 86400l ; s_since -= d_since * 86400l ; h_since = s_since / 3600l ; s_since -= h_since * 3600l ; m_since = s_since / 60l ; s_since -= m_since * 60l ; (void) printf("(%05ld.%02ld:%02ld:%02ld%s)\n", d_since,h_since,m_since,s_since,backward); return; } #endif /* SINCE */ /* * stat_it() - Actually stat and format results from file. (rsk) * exit - OKAY if no problems encountered * FAIL if couldn't open or other nastiness * */ static void stat_it(filename) char *filename; { static int fBeenHere = 0; auto char *pwn, *grn; #ifdef SINCE auto time_t time_temp; #endif /* SINCE */ #if defined(S_IFLNK) register int count; #endif #ifdef eta10 register int cpid; #endif /* eta10 */ if (fBeenHere) putchar('\n'); fBeenHere = 1; #if defined(S_IFLNK) if (-1 == lstat(filename,&Sbuf)) { fprintf(stderr,"%s: lstat: %s: %s\n", progname, filename, strerror(errno)); return; } #else if (-1 == stat(filename, &Sbuf)) { fprintf(stderr,"%s: stat: %s: %s\n", progname, filename, strerror(errno)); return; } #endif #if defined(S_IFLNK) if (S_IFLNK == (Sbuf.st_mode & S_IFMT)) { if (-1 == (count = readlink(filename,Lbuf,LBUFSIZ))) { fprintf(stderr,"%s: readlink: %s: %s\n", progname, filename, strerror(errno)); return; } if (count < LBUFSIZ) Lbuf[count] = '\0'; if (fOnePerLine) (void) printf("File: \"%s\" -> \"%s\"\n",filename,Lbuf); else (void) printf(" File: \"%s\" -> \"%s\"\n",filename,Lbuf); } else #endif { if (fOnePerLine) (void) printf("File: \"%s\"\n", filename); else (void) printf(" File: \"%s\"\n", filename); if (fOnePerLine) (void) printf("Size: %-10ld\n", Sbuf.st_size); else (void) printf(" Size: %-10ld", Sbuf.st_size); if (fOnePerLine) (void) printf("Allocated Blocks: %-10ld\n", Sbuf.st_blocks); else (void) printf(" Allocated Blocks: %-10ld", Sbuf.st_blocks); } if (fOnePerLine) (void) printf("Filetype: "); else (void) printf(" Filetype: "); switch (Sbuf.st_mode & S_IFMT) { case S_IFDIR: (void) printf("Directory\n"); break; case S_IFCHR: (void) printf("Character Device\n"); break; case S_IFBLK: (void) printf("Block Device\n"); break; case S_IFREG: (void) printf("Regular File\n"); break; #if defined(S_IFLNK) case S_IFLNK: (void) printf("Symbolic Link\n"); break; #endif #if defined(S_IFSOCK) case S_IFSOCK: (void) printf("Socket\n"); break; #endif #if defined(S_IFIFO) case S_IFIFO: (void) printf("Fifo File\n"); break; #endif #if defined(S_IFCTG) case S_IFCTG: (void) printf("Contiguous File\n"); break; #endif default: (void) printf("Unknown\n"); break; } (void) strcpy(acMode,"----------"); if (Sbuf.st_mode & S_ISVTX) /* Sticky bit */ acMode[9] = (Sbuf.st_mode & (S_IEXEC>>6)) ? 't' : 'T'; else if (Sbuf.st_mode & (S_IEXEC>>6)) /* Other execute */ acMode[9] = 'x'; if (Sbuf.st_mode & (S_IWRITE>>6)) /* Other write */ acMode[8] = 'w'; if (Sbuf.st_mode & (S_IREAD>>6)) /* Other read */ acMode[7] = 'r'; /* Sun's the 'S' is a 'l' if no execute bits are set * see thelocking description in ls(1) --ksb */ if (Sbuf.st_mode & S_ISGID) /* Set group id */ acMode[6] = 0 != (Sbuf.st_mode & 0010) ? 's' : 0 == (Sbuf.st_mode & 0111) ? 'l' : 'S'; else if (Sbuf.st_mode & (S_IEXEC>>3)) /* Group execute */ acMode[6] = 'x'; if (Sbuf.st_mode & (S_IWRITE>>3)) /* Group write */ acMode[5] = 'w'; if (Sbuf.st_mode & (S_IREAD>>3)) /* Group read */ acMode[4] = 'r'; if (Sbuf.st_mode & S_ISUID) /* Set user id */ acMode[3] = 0 != (Sbuf.st_mode & 0100) ? 's' : 'S'; else if (Sbuf.st_mode & S_IEXEC) /* User execute */ acMode[3] = 'x'; if (Sbuf.st_mode & S_IWRITE) /* User write */ acMode[2] = 'w'; if (Sbuf.st_mode & S_IREAD) /* User read */ acMode[1] = 'r'; switch (Sbuf.st_mode & S_IFMT) { /* node type */ case S_IFDIR: acMode[0] = 'd'; break; case S_IFCHR: acMode[0] = 'c'; break; case S_IFBLK: acMode[0] = 'b'; break; case S_IFREG: acMode[0] = '-'; break; #if defined(S_IFLNK) case S_IFLNK: acMode[0] = 'l'; break; #endif #if defined(S_IFSOCK) case S_IFSOCK: acMode[0] = 's'; break; #endif #if defined(S_IFIFO) case S_IFIFO: acMode[0] = 'p'; break; #endif #if defined(S_IFCTG) case S_IFCTG: acMode[0] = 'C'; break; #endif default: acMode[0] = '?'; break; } if (fOnePerLine) (void) printf("Mode: (%04o/%s)\n", Sbuf.st_mode&07777,acMode); else (void) printf(" Mode: (%04o/%s)", Sbuf.st_mode&07777,acMode); (void) setpwent(); if ((struct passwd *)0 == (pwent = getpwuid(Sbuf.st_uid))) { pwn = "???"; } else { pwn = pwent->pw_name; } if (fOnePerLine) (void) printf("Uid: (%d/%s)\n", Sbuf.st_uid, pwn); else (void) printf(" Uid: (%5d/%8s)", Sbuf.st_uid, pwn); (void) setgrent(); if ((struct group *)0 == (grent = getgrgid(Sbuf.st_gid))) { grn = "???"; } else { grn = grent->gr_name; } if (fOnePerLine) (void) printf("Gid: (%d/%s)\n", Sbuf.st_gid, grn); else (void) printf(" Gid: (%5d/%8s)\n", Sbuf.st_gid, grn); (void) printf("Device:"); #ifdef eta10 cpid = devcpuid(Sbuf.st_dev); if (iscpid(cpid)) (void) printf(" CPU%d ", cpnum(cpid)); else if (isiopid(cpid)) (void) printf(" IOU%d IOP%d VME%d", iounum(cpid), iopnum(cpid), vmenum(cpid)); else (void) printf(" CPID 0x%04x ", cpid); #endif /* eta10 */ #if !defined(major) #define major(x) (((unsigned)(x)>>16)&0xffff) #endif #if !defined(minor) #define minor(x) ((x)&0xffff) #endif (void) printf(" %2d,%-2d", major(Sbuf.st_dev), minor(Sbuf.st_dev)); if (fOnePerLine) (void) printf("\n"); if (fOnePerLine) (void) printf("Inode: %-10ld\n", (long)Sbuf.st_ino); else (void) printf(" Inode: %-10ld", (long)Sbuf.st_ino); (void) printf("Links: %-5d", Sbuf.st_nlink); /* Only meaningful if file is device */ if (S_IFCHR == (Sbuf.st_mode & S_IFMT) || S_IFBLK == (Sbuf.st_mode & S_IFMT)) { #ifdef eta10 (void) printf("\n Type: "); cpid = devcpuid(Sbuf.st_rdev); if (iscpid(cpid)) (void) printf("CPU%d ", cpnum(cpid)); else if (isiopid(cpid)) (void) printf("IOU%d IOP%d VME%d", iounum(cpid), iopnum(cpid), vmenum(cpid)); else (void) printf("CPID 0x%04x ", cpid); #else /* not eta10 */ if (fOnePerLine) (void) printf("\nDevice type:"); else (void) printf(" Device type:"); #endif /* eta10 */ (void) printf(" %2d,%-2d\n", major(Sbuf.st_rdev), minor(Sbuf.st_rdev)); } else { (void) printf("\n"); } /* The %.24s strips the newline from the ctime() string */ #ifdef SINCE #if HAVE_BIRTHTIME time_temp = Sbuf.st_birthtime; (void) printf("Birth: %.24s",ctime(&time_temp)); tsince(time_temp); #endif time_temp = Sbuf.st_atime; (void) printf("Access: %.24s",ctime(&time_temp)); tsince(time_temp); time_temp = Sbuf.st_mtime; (void) printf("Modify: %.24s",ctime(&time_temp)); tsince(time_temp); time_temp = Sbuf.st_ctime; (void) printf("Change: %.24s",ctime(&time_temp)); tsince(time_temp); #else /* SINCE */ #if HAVE_BIRTHTIME (void) printf("Birth: %s",ctime(&Sbuf.st_birthtime)); #endif (void) printf("Access: %s",ctime(&Sbuf.st_atime)); (void) printf("Modify: %s",ctime(&Sbuf.st_mtime)); (void) printf("Change: %s",ctime(&Sbuf.st_ctime)); #endif /* SINCE */ } %% boolean '1' { named "fOnePerLine" help "output one attribute per line (was -)" } every { named "stat_it" parameter "nodes" help "names to stat" }