#include "V.h"
#include "sys_stat.h"

/*** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* CALL:
*   void dmpstat(fp,sp)
*   	FILE*fp;
*   	STat*sp;
*
* DESCRIPTION:
*
* Here's a routine to produce a symbolic dump of a status  block.   Note  the
* inclusion of a stream pointer as an arg, so the caller can tell us to write
* to stdout, stderr, Vout, or any other stream.
*
* RETURNS: nothing.
*
* AUTHOR: John Chambers.
*
* CHANGES:
***/
FCT void dmpstat(fp,sp)
	FILE*fp;
	STat*sp;
{	int  type;
	V6 "Dump struct stat %08lX.",sp D;
	if (!sp) {
		V1 "### dmpstat(0) called ###" D;
		return;
	}
#if defined(USE_pthreads) && (USE_pthreads > 0)
	if (V_locking && use_pthreads) {
		pthread_lock_global_np();
		P6 "\t\t\tpthread_lock_global_np() in %s",Fctname D;
		fflush(Vout);
	}
#endif /*USE_pthreads*/
	fprintf(fp,"\t dev=%04X=%u [%d,%d]"				/* dev_t */
		,sp->st_dev,sp->st_dev,major(sp->st_dev),minor(sp->st_dev));
	fprintf(fp,"\trdev=%04X=%u [%d,%d]\n"				/* rdev_t */
		,sp->st_rdev,sp->st_rdev,major(sp->st_rdev),minor(sp->st_rdev));

	fprintf(fp,"\t ino=%04X=%u",sp->st_ino,sp->st_ino);	/* Ushort */
	fprintf(fp,"\tnlink=%u"     ,sp->st_nlink);	/* short */
	fprintf(fp,"\tsize=%u\n"     ,sp->st_size );	/* off_t */

	fprintf(fp,"\tmode=0%o"    ,sp->st_mode );			/* Ushort */
	fprintf(fp,"\t  uid=%u"     ,sp->st_uid  );	/* Ushort */
	fprintf(fp,"\tgid=%u\n"     ,sp->st_gid  );	/* Ushort */

	type = sp->st_mode & S_IFMT;
	switch (type ) {
	  case S_IFDIR: fprintf(fp,"\t\tIFDIR	directory\n"); break;
	  case S_IFCHR: fprintf(fp,"\t\tIFCHR	character special\n"); break;
	  case S_IFBLK: fprintf(fp,"\t\tIFBLK	block special\n"); break;
	  case S_IFREG: fprintf(fp,"\t\tIFREG	regular file\n"); break;
#ifdef S_IFLNK
	  case S_IFLNK: fprintf(fp,"\t\tIFLNK	symlink\n"); break;
#endif
#ifdef S_IFSOCK
	  case S_IFSOCK: fprintf(fp,"\t\tIFSOCK	socket\n"); break;
#endif
#ifdef S_IFPORT
	  case S_IFPORT: fprintf(fp,"\t\tIFPORT	port\n"); break;
#endif
#ifdef SYS5
#ifdef S_IFIFO
	  case S_IFIFO: fprintf(fp,"\t\tIFIFO	named pipe\n"); break;
#endif
#ifdef S_IFNAM
	  case S_IFNAM: fprintf(fp,"\t\tIFNAM	special named file\n"); break;
#endif
#endif
#ifdef XENIX
#ifdef S_INSEM	/* S_INSEM 01 -- XENIX semaphore subtype of IFNAM file */
	  case S_INSEM: fprintf(fp,"\t\tINSEM	semaphore\n"); break;
#endif
#ifdef S_INSHD	/* S_INSHD 02 -- XENIX shared data subtype of IFNAM file */
	  case S_INSHD: fprintf(fp,"\t\tINSHD	shared data\n"); break;
#endif
#endif
	  default:
		fprintf(fp,"\t\t0%06o	unknown file type.\n"); break;
	}
	if (sp->st_mode & S_ISUID)
		fprintf(fp,"\t\tISUID	set user id on execution\n");
	if (sp->st_mode & S_ISGID) {			/* setgid if executable */
		if (sp->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
			 fprintf(fp,"\t\tISGID	set group id on execution\n");
		else fprintf(fp,"\t\tENFMT	record locking enforcement flag\n");
	}
	if (sp->st_mode & S_ISVTX)
		fprintf(fp,"\t\tISVTX	save swapped text after use\n");

	fprintf(fp,"\tatime=%08X=%24.24s\n",sp->st_atime,ctime(&sp->st_atime));
	fprintf(fp,"\tmtime=%08X=%24.24s\n",sp->st_mtime,ctime(&sp->st_mtime));
	fprintf(fp,"\tctime=%08X=%24.24s\n",sp->st_ctime,ctime(&sp->st_ctime));
#if defined(USE_pthreads) && (USE_pthreads > 0)
	if (V_locking && use_pthreads) {
		P6 "\t\t\tpthread_unlock_global_np() in %s",Fctname D;
		fflush(Vout);
		pthread_unlock_global_np();
	}
#endif /*USE_pthreads*/
	return;
}
