/*-
* Copyright (c)1997-2005 by Hartmut Brandt
* All rights reserved.
*
* Author: Harti Brandt <harti@freebsd.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Begemot: libbegemot/prstat.c,v 1.18 2005/06/01 08:01:45 brandt_h Exp $
*/
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_SYSMACROS_H
#include <sys/sysmacros.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include "begemot.h"
#ifdef TIMESPEC_HAS_TS
#define TV_SEC ts_sec
#define TV_NSEC ts_nsec
#else
#define TV_SEC tv_sec
#define TV_NSEC tv_nsec
#endif
#define CB(B,F) ((B & F) != 0)
/*
* Print the contents of a stat buffer onto a file
*/
void
prstat(FILE *fp, const struct stat *sb)
{
#if defined(STAT_HAS_TIMESPEC) || defined(STAT_HAS_TIMEVAL)
char tbuf[512];
time_t clk;
#else
char *tval;
#endif
#ifdef STAT_HAS_FLAGS
int first;
#endif
(void)fprintf(fp, "st_dev = (%lu,%lu)\n",
(u_long)major(sb->st_dev),
(u_long)minor(sb->st_dev));
(void)fprintf(fp, "st_ino = %lu\n", (u_long)sb->st_ino);
(void)fprintf(fp, "st_mode = ");
switch (sb->st_mode & S_IFMT) {
case S_IFIFO:
(void)putc('f', fp);
break;
case S_IFCHR:
(void)putc('c', fp);
break;
case S_IFDIR:
(void)putc('d', fp);
break;
#ifdef IFNAM
case S_IFNAM:
(void)putc('n', fp);
break;
#endif
case S_IFBLK:
(void)putc('b', fp);
break;
case S_IFREG:
(void)putc('-', fp);
break;
case S_IFLNK:
(void)putc('l', fp);
break;
case S_IFSOCK:
(void)putc('s', fp);
break;
#ifdef IFDOOR
case S_IFDOOR:
(void)putc('o', fp);
break;
#endif
#ifdef IFWHT
case S_IFWHT:
(void)putc('w', fp);
break;
#endif
default:
(void)fprintf(fp, "type=0x%lx", (u_long)((sb->st_mode & S_IFMT) >> 12));
break;
}
(void)putc(' ', fp);
if(sb->st_mode & S_ISUID)
(void)fprintf(fp, "suid ");
if(sb->st_mode & S_ISGID)
(void)fprintf(fp, "sgid ");
if(sb->st_mode & S_ISVTX)
(void)fprintf(fp, "vtx ");
(void)fprintf(fp, "%c%c%c%c%c%c%c%c%c",
"-r"[CB(S_IRUSR, sb->st_mode)],
"-w"[CB(S_IWUSR, sb->st_mode)],
"-x"[CB(S_IXUSR, sb->st_mode)],
"-r"[CB(S_IRGRP, sb->st_mode)],
"-w"[CB(S_IWGRP, sb->st_mode)],
"-x"[CB(S_IXGRP, sb->st_mode)],
"-r"[CB(S_IROTH, sb->st_mode)],
"-w"[CB(S_IWOTH, sb->st_mode)],
"-x"[CB(S_IXOTH, sb->st_mode)]);
(void)putc('\n', fp);
(void)fprintf(fp, "st_nlink = %lu\n", (u_long)sb->st_nlink);
(void)fprintf(fp, "st_uid = %ld\n", (long)sb->st_uid);
(void)fprintf(fp, "st_gid = %ld\n", (long)sb->st_gid);
(void)fprintf(fp, "st_rdev = (%lu,%lu)\n",
(u_long)major(sb->st_rdev),
(u_long)minor(sb->st_rdev));
(void)fprintf(fp, "st_size = %ld\n", (long)sb->st_size);
#ifdef STAT_HAS_TIMESPEC
clk = sb->st_atimespec.TV_SEC;
(void)strftime(tbuf, sizeof(tbuf), "%Y %T", gmtime(&clk));
(void)sprintf(tbuf + strlen(tbuf), ".%09lu", sb->st_atimespec.TV_NSEC);
(void)fprintf(fp, "st_atime = %s\n", tbuf);
clk = sb->st_mtimespec.TV_SEC;
(void)strftime(tbuf, sizeof(tbuf), "%Y %T", gmtime(&clk));
(void)sprintf(tbuf + strlen(tbuf), ".%09lu", sb->st_mtimespec.TV_NSEC);
(void)fprintf(fp, "st_mtime = %s\n", tbuf);
clk = sb->st_ctimespec.TV_SEC;
(void)strftime(tbuf, sizeof(tbuf), "%Y %T", gmtime(&clk));
(void)sprintf(tbuf + strlen(tbuf), ".%09lu", sb->st_ctimespec.TV_NSEC);
(void)fprintf(fp, "st_ctime = %s\n", tbuf);
#elif defined(STAT_HAS_TIMEVAL)
clk = sb->st_atim.tv_sec;
(void)strftime(tbuf, sizeof(tbuf), "%Y %T", gmtime(&clk));
(void)sprintf(tbuf + strlen(tbuf), ".%06lu", sb->st_atim.tv_nsec);
(void)fprintf(fp, "st_atime = %s\n", tbuf);
clk = sb->st_mtim.tv_sec;
(void)strftime(tbuf, sizeof(tbuf), "%Y %T", gmtime(&clk));
(void)sprintf(tbuf + strlen(tbuf), ".%06lu", sb->st_mtim.tv_nsec);
(void)fprintf(fp, "st_mtime = %s\n", tbuf);
clk = sb->st_ctim.tv_sec;
(void)strftime(tbuf, sizeof(tbuf), "%Y %T", gmtime(&clk));
(void)sprintf(tbuf + strlen(tbuf), ".%06lu", sb->st_ctim.tv_nsec);
(void)fprintf(fp, "st_ctime = %s\n", tbuf);
#else
tval = asctime(gmtime(&sb->st_atime));
(void)fprintf(fp, "st_atime = %s", tval);
tval = asctime(gmtime(&sb->st_mtime));
(void)fprintf(fp, "st_mtime = %s", tval);
tval = asctime(gmtime(&sb->st_ctime));
(void)fprintf(fp, "st_ctime = %s", tval);
#endif
(void)fprintf(fp, "st_blksize = %ld\n", (long)sb->st_blksize);
(void)fprintf(fp, "st_blocks = %"QUADFMT"d\n", (u_int64_t)sb->st_blocks);
#ifdef STAT_HAS_FSTYPE
(void)fprintf(fp, "st_fstype = %.*s\n", (int)sizeof(sb->st_fstype), sb->st_fstype);
#endif
#ifdef STAT_HAS_FLAGS
(void)fprintf(fp, "st_flags = %08lx<", (u_long)sb->st_flags);
#define PRFLAG(L,S) \
if (sb->st_flags & L) { \
if (!first) \
(void)fprintf(fp, ","); \
else \
first = 0; \
(void)fprintf(fp, #S); \
}
first = 1;
#ifdef UF_NODUMP
PRFLAG(UF_NODUMP, nodump);
#endif
#ifdef UF_IMMUTABLE
PRFLAG(UF_IMMUTABLE, uimmutable);
#endif
#ifdef UF_APPEND
PRFLAG(UF_APPEND, uappend)
#endif
#ifdef UF_OPAQUE
PRFLAG(UF_OPAQUE, opaque)
#endif
#ifdef UF_NOUNLINK
PRFLAG(UF_NOUNLINK, unounlink)
#endif
#ifdef SF_ARCHIVED
PRFLAG(SF_ARCHIVED, archived)
#endif
#ifdef SF_IMMUTABLE
PRFLAG(SF_IMMUTABLE, simmutable)
#endif
#ifdef SF_APPEND
PRFLAG(SF_APPEND, sappend)
#endif
#ifdef SF_NOUNLINK
PRFLAG(SF_NOUNLINK, snounlink)
#endif
#ifdef SF_SNAPSHOT
PRFLAG(SF_SNAPSHOT, snapshot)
#endif
#undef PRFLAG
(void)fprintf(fp, ">\n");
#endif
#ifdef STAT_HAS_GEN
(void)fprintf(fp, "st_gen = %u\n", sb->st_gen);
#endif
#ifdef STAT_HAS_BIRTHTIMESPEC
clk = sb->st_birthtimespec.TV_SEC;
(void)strftime(tbuf, sizeof(tbuf), "%Y %T", gmtime(&clk));
(void)sprintf(tbuf + strlen(tbuf), ".%09lu", sb->st_birthtimespec.TV_NSEC);
(void)fprintf(fp, "st_birthtime = %s\n", tbuf);
#endif
}
#ifdef TEST
#include <string.h>
#include <errno.h>
int
main(int argc, char *argv[])
{
struct stat statb;
if (fstat(0, &statb))
panic("cannot stat stdin: %s", strerror(errno));
prstat(stdout, &statb);
return (0);
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1