home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
-
- N O T I C E : Copyright 1991,1992,1993 (c) Scott Fehrman
-
- This program and it's related documents may be distributed
- and/or copied without charge. The related source code and
- executable files may be used freely providing that all
- copyright notices and information about the author and
- company are not removed or altered in any manner. The users
- of this program and it's related documents understand that
- this material is provided "as is" with no warranty. The
- author and/or company are not responsible for any
- "side effects" and/or problems that this material may have
- on system and/or application files and data. The use of this
- program and it's related material implies that the user
- understands the terms and conditions for which it is provided.
-
- Program: pd.c
-
- Author: Scott L. Fehrman, Systems Engineer
- Sun Microsystems Computer Corporation
- Two Pierce Place
- Suite 1500
- Itasca, IL 60173
- (708) 285-7632
- scott.fehrman@Central.Sun.COM
-
- ***************************************************************************/
-
- /*** include system header files ***/
-
- #include <stdio.h> /* standard unix input/output facilities */
- #include <time.h> /* file date/time data */
- #include <sys/types.h> /* system types used by <sys/stat.h> */
- #include <sys/param.h> /* machine dependant paramters */
- #include <dirent.h> /* directory entry information */
- #include <sys/stat.h> /* status information about files */
- #include <malloc.h> /* dyn memory allocation */
- #include <errno.h> /* error handling */
- #include <pwd.h> /* passwd file data */
- #include <grp.h> /* group file data */
-
- /*** define constant variables ***/
-
- #define VERSION "3.3.1" /* program revision stamp */
- #define MAX_NAME_LEN 60 /* max character length of a file name */
- #define MAX_ERROR_LEN 60 /* max character length of error mess */
- #define SCREEN_WIDTH 80 /* number of characters on screen, max */
- #define TRUE 1 /* define the TRUE value */
- #define FALSE 0 /* define the FALSE value */
- #define NUM_BLANK 2 /* blank characters between columns */
- #define ENV_NAME "PD" /* environment variable options */
- #define ENTRY_FILE 0
- #define ENTRY_DIR 1
- #define CMD_DIR 2
-
- /*** define macros if needed ***/
-
- #ifndef S_ISDIR
- #define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* is a directory */
- #endif
-
- #ifndef SVR3
- #ifndef S_ISLNK
- #define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* is symbolic link */
- #endif
- #endif
-
- #ifndef S_ISBLK
- #define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* is block device */
- #endif
-
- #ifndef S_ISCHR
- #define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* is char device */
- #endif
-
- #ifndef major
- #define major(dev) (((dev) >> 8) & 0xff) /* device major # */
- #endif
-
- #ifndef minor
- #define minor(dev) ((dev) & 0xff) /* device minor # */
- #endif
-
- /*** function prototypes ***/
-
- int open_directory(); /* open the directory */
- int sort_name(); /* func for qsort() by file name, default */
- int sort_date_modified(); /* func for qsort() by date modified */
- int sort_size(); /* func for qsort() by file size */
- int sort_rev_name(); /* func for qsort() by file name, reverse */
- int sort_rev_date_modified(); /* func for qsort() by date modified, rev */
- int sort_rev_size(); /* func for qsort() by file size, rev */
- void entry_store(); /* store entry in ptr array */
- void entry_release(); /* release allocated memory for arrays */
- void process_cmd_dir(); /* process the dirs on command line */
- void process_cmd_file(); /* process the files on command line */
- void command_option(); /* command line option */
- void process_directory(); /* process the opened directory */
- void display_header(); /* print header data (pathname) */
- void read_directory(); /* read the files in the open directory */
- void close_directory(); /* close the directory */
- void display_directory(); /* display directory as "n" columns */
- void display_expanded(); /* display entry in expanded format */
- void getenv_option(); /* get any environment options */
- void stat_file(); /* get file status from argument */
- void align_column(); /* align output to a specific column */
- void repeat_char(); /* repeat a character # of times */
- void program_usage(); /* if error, how to use program */
- void program_help(); /* help with this program */
- void program_version(); /* display version stamp */
-
- /*** declare variables ***/
-
- typedef struct EntryTag { /* struct for entries */
- char szName[MAX_NAME_LEN]; /* entry name */
- int iSize; /* entry size */
- int iMod; /* entry date modified */
- } EntryData;
-
- extern char *getenv(); /* ptr to external string */
-
- EntryData *File, /* ptr to array, files */
- *Dir, /* ptr to array, directories */
- *Cmd; /* ptr to array, cmd line dirs */
-
- char *szProgName, /* program name argv[0] */
- szDirName[MAX_NAME_LEN], /* dir name argv[0+x] */
- cQtyChar = '.'; /* qty terminating char */
-
- int iAllocFile = 100, /* # files to alloc memory */
- iAllocDir = 100, /* # dirs to alloc memory */
- iAllocCmd = 100, /* # cmd dirs to alloc memory */
- iReturn, /* Return value */
- iCmdFiles = 0, /* qty cmd line files */
- iCmdDirs = 0, /* qty cmd line dirs */
- iRemoteDir = FALSE, /* is remote directory */
- iNumFiles, /* counter # files */
- iNumDirs, /* counter # dirs */
- iNumEntries = 0, /* counter total entries */
- iLongest, /* length of longest name */
- iNumColumns, /* # of columns to display */
- iScrWidth = SCREEN_WIDTH, /* Screen width # columns */
- iSortOptions = 0, /* qty of sort options */
- iFlagAbort = FALSE, /* flag, do not run -h, -v */
- iFlagAccessed = FALSE, /* flag, date/time accessed */
- iFlagAltOutput = FALSE, /* flag, alternate output */
- iFlagBrief = FALSE, /* flag, brief output */
- iFlagCount = FALSE, /* flag, count entries only */
- iFlagDirs = TRUE, /* flag, show files */
- iFlagDot = TRUE, /* flag, show files start with .*/
- iFlagFiles = TRUE, /* flag, show directories */
- iFlagHidden = FALSE, /* flag, show "." & ".." */
- iFlagHeader = TRUE, /* flag, show header extn dis */
- iFlagInode = FALSE, /* flag, show file inode # */
- iFlagLink = FALSE, /* flag, show link status */
- iFlagLinkCnt = FALSE, /* flag, show file link count */
- iFlagModified = FALSE, /* flag, date/time modified */
- iFlagPath = TRUE, /* flag, show pathname */
- iFlagPro = FALSE, /* flag, protection data */
- iFlagQty = TRUE, /* flag, show qty of entries */
- iFlagReverse = FALSE, /* flag, reverse sort */
- iFlagSingle = FALSE, /* flag, single column */
- iFlagSize = FALSE, /* flag, size & owner data */
- iFlagSort = TRUE, /* flag, sort files -ns */
- iFlagSortModified = FALSE, /* flag, sort date modified */
- iFlagSortSize = FALSE, /* flag, sort file size */
- iFlagStatus = FALSE, /* flag, date/time stat mod */
- iFlagWide = FALSE, /* flag, wide format 132 col */
- iFilesOnly = FALSE; /* flag, cmd line, files only */
-
- DIR *dirp; /* ptr to dir struct DIR */
- struct dirent *filep; /* ptr to file struct dirent */
- struct stat stb; /* ptr to file status struct */
- struct tm *tmp; /* ptr to time/date struct */
- struct passwd *passwdp; /* ptr to passwd struct */
- struct group *groupp; /* ptr to group struct */
-
- /**********************************************************************/
- int main(argc, argv)
- /**********************************************************************
-
- main function: "returns an integer"
-
- * check the environment varaible for any program options.
- * allocate an inital amount of memory for storing entries
- * parse the command line: ( we don't care about the order )
- * seperate the file/dir names from the options,
- * for each file, store name in file array
- * for each directory, store name in directory array
- * if no "command-line" files or dirs, add the current dir "." to array
- * if files found, call function to process them
- * if directories found, call function to process them
-
- **********************************************************************/
- int argc;
- char *argv[];
- {
- register int t;
- int iTemp;
- char szError[MAX_ERROR_LEN],
- szOption[MAX_NAME_LEN];
-
- iReturn = 0;
- szProgName = argv[0];
- getenv_option();
-
- File = (EntryData *)malloc((unsigned int)(sizeof(EntryData)*iAllocFile));
- Dir = (EntryData *)malloc((unsigned int)(sizeof(EntryData)*iAllocDir));
- Cmd = (EntryData *)malloc((unsigned int)(sizeof(EntryData)*iAllocCmd));
-
- if ( !File || !Dir || !Cmd ) {
- (void)sprintf(szError,"%s: malloc()",szProgName);
- perror(szError);
- exit(TRUE);
- }
-
- for ( t=1 ; t<argc ; t++ ) {
- if ( argv[t][0] == '-' ) {
- (void)strcpy(szOption,++argv[t]);
- command_option(szOption);
- }
- else {
- iRemoteDir = TRUE;
- if ( !iFlagAbort ) {
- if ( stat(argv[t], &stb) < 0 ) { /* valid file */
- #ifdef SVR3
- iFlagAbort = TRUE;
- iReturn = TRUE;
- (void)sprintf(szError,"%s: %s",szProgName,argv[t]);
- perror(szError);
- #else
- if ( lstat(argv[t], &stb) < 0 ) { /* maybe a link */
- iFlagAbort = TRUE;
- iReturn = TRUE;
- (void)sprintf(szError,"%s: %s",szProgName,argv[t]);
- perror(szError);
- }
- else {
- entry_store(ENTRY_FILE,argv[t],
- (int)stb.st_mtime,(int)stb.st_size,iCmdFiles++);
- }
- #endif
- }
- else { /* valid entry */
- if ( S_ISDIR(stb.st_mode) ) { /* directory */
- entry_store(CMD_DIR,argv[t],0,0,iCmdDirs++);
- }
- else { /* file */
- iTemp = strlen(argv[t]);
- if ( iTemp > iLongest ) iLongest = iTemp;
- entry_store(ENTRY_FILE,argv[t],
- (int)stb.st_mtime,(int)stb.st_size,iCmdFiles++);
- }
- }
- }
- }
- }
- if ( !iCmdFiles && !iCmdDirs ) {
- entry_store(CMD_DIR,".",0,0,iCmdDirs++);
- }
- if ( !iFlagAbort ) {
- if ( iCmdFiles && iFlagFiles )
- process_cmd_file(iCmdFiles);
- if ( iCmdDirs ) {
- process_cmd_dir(iCmdDirs);
- entry_release(CMD_DIR);
- }
- entry_release(ENTRY_FILE);
- entry_release(ENTRY_DIR);
- }
- return(iReturn);
- }
-
- /**********************************************************************/
- void entry_store(iType,pszName,iMod,iSize,iCount)
- /**********************************************************************
-
- entry store function: "returns nothing"
-
- * receives a pointer to entry name, type, modify date, size, and count
- * places data into proper pointer array depending on the type
- * each array is checked for memory overflow
- * if overflow, then realloc() is called to double memory size
-
- **********************************************************************/
- char *pszName;
- int iType,
- iMod,
- iSize,
- iCount;
- {
- char szError[MAX_ERROR_LEN];
- switch ( iType ) {
- case CMD_DIR:
- if ( iCount == iAllocCmd ) {
- iAllocCmd *= 2;
- Cmd = (EntryData *)realloc(
- (char *)Cmd,
- (unsigned int)(sizeof(EntryData)*iAllocCmd));
- if ( !Cmd ) {
- (void)sprintf(szError,"%s: realloc()",szProgName);
- perror(szError);
- exit(1);
- }
- }
- (void)strcpy(Cmd[iCount].szName,pszName);
- break;
- case ENTRY_FILE:
- if ( iCount == iAllocFile ) {
- iAllocFile *= 2;
- File = (EntryData *)realloc(
- (char *)File,
- (unsigned int)(sizeof(EntryData)*iAllocFile));
- if ( !File ) {
- (void)sprintf(szError,"%s: realloc()",szProgName);
- perror(szError);
- exit(1);
- }
- }
- (void)strcpy(File[iCount].szName,pszName);
- File[iCount].iMod = iMod;
- File[iCount].iSize = iSize;
- break;
- case ENTRY_DIR:
- if ( iCount == iAllocDir ) {
- iAllocDir *= 2;
- Dir = (EntryData *)realloc(
- (char *)Dir,
- (unsigned int)(sizeof(EntryData)*iAllocDir));
- if ( !Dir ) {
- (void)sprintf(szError,"%s: realloc()",szProgName);
- perror(szError);
- exit(1);
- }
- }
- (void)strcpy(Dir[iCount].szName,pszName);
- Dir[iCount].iMod = iMod;
- Dir[iCount].iSize = iSize;
- break;
- }
- return;
- }
-
- /**********************************************************************/
- void entry_release(iType)
- /**********************************************************************
-
- entry release function: "returns nothing"
-
- * receives an entry type
- * releases the allocated memory for the given type
-
- **********************************************************************/
- int iType;
- {
- switch ( iType ) {
- case CMD_DIR:
- (void)free((char *)Cmd);
- break;
- case ENTRY_FILE:
- (void)free((char *)File);
- break;
- case ENTRY_DIR:
- (void)free((char *)Dir);
- break;
- }
- return;
- }
-
- /**********************************************************************/
- void process_cmd_dir(iDir)
- /**********************************************************************
-
- process command-line directory: "returns nothing"
-
- * reads each directory name in the pointer array
- * for each name, the directory is opened then processed
-
- **********************************************************************/
- int iDir;
- {
- register int i;
- for ( i=0 ; i<iDir ; i++ ) {
- szDirName[0] = '\0';
- (void)strcpy(szDirName,Cmd[i].szName);
- if ( open_directory() ) process_directory();
- }
- return;
- }
-
- /**********************************************************************/
- void process_cmd_file(iFile)
- /**********************************************************************
-
- process command-line file: "returns nothing"
-
- * the files in the pointer array are sorted depending on the options
- * the display_directory function is called
-
- **********************************************************************/
- int iFile;
- {
- int iTemp;
- iNumFiles = iFile;
- iNumEntries = iFile;
- iNumDirs = 0;
- iNumColumns = iScrWidth / ( iLongest+NUM_BLANK );
- if ( iFlagSingle ) iNumColumns = 1;
- szDirName[0] = '\0';
- if ( iNumFiles ) {
- if ( iFlagSort && iNumFiles > 1 ) {
- if ( iFlagReverse )
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_rev_name);
- else
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_name);
- }
- else if ( iFlagSortModified && iNumFiles > 1 ) {
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_name);
- if ( iFlagReverse )
- qsort((char *)File,iNumFiles,sizeof(EntryData),
- sort_rev_date_modified);
- else
- qsort((char *)File,iNumFiles,sizeof(EntryData),
- sort_date_modified);
- }
- else if ( iFlagSortSize && iNumFiles > 1 ) {
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_name);
- if ( iFlagReverse )
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_rev_size);
- else
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_size);
- }
- iTemp = iFlagPath;
- iFlagPath = FALSE;
- iFilesOnly = TRUE;
- display_directory();
- iFlagPath = iTemp;
- iFilesOnly = FALSE;
- }
- return;
- }
-
- /**********************************************************************/
- void getenv_option()
- /**********************************************************************
-
- get environment options: "returns nothing"
-
- * calls the getenv() system function
- * the character array is parsed for multiple options
- * for each option, the command_option() pd function is called
- * set the qty terminating character if ENV options are used
-
- **********************************************************************/
- {
- register int i, j;
- int iChar;
- char *szEnv = getenv(ENV_NAME),
- szOption[MAX_NAME_LEN];
- if ( szEnv != NULL ) {
- cQtyChar = ':';
- if ( (iChar = strlen(szEnv)) ) {
- szOption[0] = '\0';
- j=0;
- for ( i=0 ; i<iChar ; i++ ) {
- if ( szEnv[i] == ' ' ) {
- if ( strlen(szOption) ) {
- szOption[j] = '\0';
- command_option(szOption);
- szOption[0] = '\0';
- j=0;
- }
- }
- else if ( szEnv[i] != '-' ) szOption[j++] = szEnv[i];
- }
- if ( strlen(szOption) ) {
- szOption[j] = '\0';
- command_option(szOption);
- }
- }
- }
- return;
- }
-
- /**********************************************************************/
- void command_option(szOption)
- /**********************************************************************
-
- command-line options: "returns nothing"
-
- * receives an option string (character array)
- * checks for a valid option name
- * if valid option then various flags are set
-
- **********************************************************************/
- char *szOption;
- {
- if ( !strcmp(szOption,"h") || !strcmp(szOption,"help") ){
- program_help();
- iFlagAbort = TRUE;
- }
- else if ( !strcmp(szOption,"a") || !strcmp(szOption,"all") ){
- iFlagHidden = TRUE;
- iFlagDot = TRUE;
- }
- else if ( !strcmp(szOption,"b") || !strcmp(szOption,"brief") ){
- iFlagBrief = TRUE;
- iFlagHeader = FALSE;
- iFlagPath = FALSE;
- iFlagQty = FALSE;
- }
- else if ( !strcmp(szOption,"c") || !strcmp(szOption,"count")){
- iFlagCount = TRUE;
- iFlagSort = FALSE;
- }
- else if ( !strcmp(szOption,"d") || !strcmp(szOption,"dir") ){
- iFlagFiles = FALSE;
- }
- else if ( !strcmp(szOption,"f") || !strcmp(szOption,"file") ){
- iFlagDirs = FALSE;
- }
- else if ( !strcmp(szOption,"r") || !strcmp(szOption,"reverse")){
- iFlagReverse = TRUE;
- }
- else if ( !strcmp(szOption,"v") || !strcmp(szOption,"version") ){
- program_version();
- iFlagAbort = TRUE;
- }
- else if ( !strcmp(szOption,"lc") || !strcmp(szOption,"link_cnt") ){
- iFlagAltOutput = TRUE;
- iFlagLinkCnt = TRUE;
- }
- else if ( !strcmp(szOption,"nd") || !strcmp(szOption,"no_dot") ){
- if ( !iFlagHidden ) iFlagDot = FALSE;
- }
- else if ( !strcmp(szOption,"nh") || !strcmp(szOption,"no_hdr") ){
- iFlagHeader = FALSE;
- }
- else if ( !strcmp(szOption,"np") || !strcmp(szOption,"no_pwd") ){
- iFlagPath = FALSE;
- }
- else if ( !strcmp(szOption,"nq") || !strcmp(szOption,"no_qty") ){
- iFlagQty = FALSE;
- }
- else if ( !strcmp(szOption,"ns") || !strcmp(szOption,"no_sort") ){
- iFlagSort = FALSE;
- }
- else if ( !strcmp(szOption,"sc") || !strcmp(szOption,"sglcol")) {
- iFlagSingle = TRUE;
- }
- else if ( !strcmp(szOption,"sm") || !strcmp(szOption,"sort_dtm")) {
- iFlagSortModified = TRUE;
- iFlagAltOutput = TRUE;
- iFlagModified = TRUE;
- iFlagSort = FALSE;
- iSortOptions++;
- }
- else if ( !strcmp(szOption,"ss") || !strcmp(szOption,"sort_size")) {
- iFlagSortSize = TRUE;
- iFlagAltOutput = TRUE;
- iFlagSize = TRUE;
- iFlagSort = FALSE;
- iSortOptions++;
- }
- else if ( !strcmp(szOption,"dta") || !strcmp(szOption,"accessed")){
- iFlagAltOutput = TRUE;
- iFlagAccessed = TRUE;
- }
- else if ( !strcmp(szOption,"dtm") || !strcmp(szOption,"modified")){
- iFlagAltOutput = TRUE;
- iFlagModified = TRUE;
- }
- else if ( !strcmp(szOption,"dts") || !strcmp(szOption,"status")){
- iFlagAltOutput = TRUE;
- iFlagStatus = TRUE;
- }
- else if ( !strcmp(szOption,"det") || !strcmp(szOption,"detail")){
- iFlagAltOutput = TRUE;
- iFlagAccessed = TRUE;
- iFlagModified = TRUE;
- iFlagStatus = TRUE;
- }
- else if ( !strcmp(szOption,"s") || !strcmp(szOption,"size")){
- iFlagAltOutput = TRUE;
- iFlagSize = TRUE;
- }
- else if ( !strcmp(szOption,"p") || !strcmp(szOption,"pro")){
- iFlagAltOutput = TRUE;
- iFlagPro = TRUE;
- }
- else if ( !strcmp(szOption,"w") || !strcmp(szOption,"wide")){
- iFlagWide = TRUE;
- iScrWidth = 132;
- }
- #ifndef SVR3
- else if ( !strcmp(szOption,"l") || !strcmp(szOption,"link")) {
- iFlagLink = TRUE;
- }
- #endif
- else if ( !strcmp(szOption,"i") || !strcmp(szOption,"inode")) {
- iFlagAltOutput = TRUE;
- iFlagInode = TRUE;
- }
- else {
- iReturn = 1;
- (void)printf("Error: Invalid option: '-%s', use '-h' for help.",szOption);
- program_usage();
- iFlagAbort = TRUE;
- }
- if ( iSortOptions > 1 ) {
- iReturn = 1;
- (void)printf("Error: incompatible sort options specified, other than '-r'.");
- program_usage();
- iFlagAbort = TRUE;
- }
- return;
- }
-
- /**********************************************************************/
- int open_directory()
- /**********************************************************************
-
- open directory: "returns an integer"
-
- * uses the dir name string (character array)
- * calls the opendir() system function
- * obtains a pointer to the directory entry
-
- **********************************************************************/
- {
- char szError[MAX_ERROR_LEN];
- int iReturnValue = FALSE;
- if ( (dirp = opendir(szDirName)) != NULL )
- iReturnValue = TRUE;
- else {
- iReturn = TRUE;
- (void)printf("\n");
- (void)sprintf(szError,"%s: %s",szProgName, szDirName);
- perror(szError);
- (void)printf("\n");
- }
- return(iReturnValue);
- }
-
- /**********************************************************************/
- void process_directory()
- /**********************************************************************
-
- process directory: "returns nothing"
-
- * reads the given directory
- * closes the directory
- * sorts the entries depending on the options
- * calls the display_directory() function
-
- **********************************************************************/
- {
- read_directory();
- close_directory();
- iNumColumns = iScrWidth / ( iLongest+NUM_BLANK );
- if ( iFlagSingle ) iNumColumns = 1;
- if ( iNumFiles+iNumDirs > 0 ) {
- if ( iFlagSort ) {
- if ( iNumFiles > 1 )
- if ( iFlagReverse )
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_rev_name);
- else
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_name);
- if ( iNumDirs > 1 )
- if ( iFlagReverse )
- qsort((char *)Dir,iNumDirs,sizeof(EntryData),sort_rev_name);
- else
- qsort((char *)Dir,iNumDirs,sizeof(EntryData),sort_name);
- }
- else if ( iFlagSortModified ) {
- if ( iNumFiles > 1 ) {
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_name);
- if ( iFlagReverse )
- qsort((char *)File,iNumFiles,sizeof(EntryData),
- sort_rev_date_modified);
- else
- qsort((char *)File,iNumFiles,sizeof(EntryData),
- sort_date_modified);
- }
- if ( iNumDirs > 1 ) {
- qsort((char *)Dir,iNumDirs,sizeof(EntryData),sort_name);
- if ( iFlagReverse )
- qsort((char *)Dir,iNumDirs,sizeof(EntryData),
- sort_rev_date_modified);
- else
- qsort((char *)Dir,iNumDirs,sizeof(EntryData),
- sort_date_modified);
- }
- }
- else if ( iFlagSortSize ) {
- if ( iNumFiles > 1 ) {
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_name);
- if ( iFlagReverse )
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_rev_size);
- else
- qsort((char *)File,iNumFiles,sizeof(EntryData),sort_size);
- }
- if ( iNumDirs > 1 ) {
- qsort((char *)Dir,iNumDirs,sizeof(EntryData),sort_name);
- if ( iFlagReverse )
- qsort((char *)Dir,iNumDirs,sizeof(EntryData),sort_rev_size);
- else
- qsort((char *)Dir,iNumDirs,sizeof(EntryData),sort_size);
- }
- }
- display_directory();
- }
- if ( !iNumEntries ) {
- iReturn = TRUE;
- (void)printf("No entries selected. \n\n");
- }
- return;
- }
-
- /**********************************************************************/
- void display_header()
- /**********************************************************************
-
- display header: "returns nothing"
-
- * show the directory pathname if local dir then use "."
- * show the quantity of entries in the directory
-
- **********************************************************************/
- {
- char *cwd, *getcwd();
- if ( iRemoteDir )
- (void)printf("%s",szDirName);
- else {
- cwd = getcwd((char *)NULL, 128);
- (void)printf("%s",cwd);
- }
- if (iNumEntries == 1)
- (void)printf(" %d Entry%c\n\n",iNumEntries,cQtyChar);
- else
- (void)printf(" %d Entries%c\n\n",iNumEntries,cQtyChar);
- return;
- }
-
- /**********************************************************************/
- void read_directory()
- /**********************************************************************
-
- read directory: "returns nothing"
-
- * reads the given directory
- * file entries are stored in the file pointer array
- * dir entries are stored in the dir pointer array
-
- **********************************************************************/
- {
- int iTemp,
- iDone = FALSE;
- char szEntry[MAX_NAME_LEN],
- szFullName[MAX_NAME_LEN],
- szError[MAX_ERROR_LEN];
-
- iTemp = 0;
- iNumFiles = 0;
- iNumDirs = 0;
- iLongest = 0;
-
- do {
- filep = readdir(dirp);
- if ( filep ) {
- (void)strcpy(szEntry,filep->d_name);
- if ( strcmp(szEntry,".") && strcmp(szEntry,"..") || iFlagHidden ) {
- (void)strcpy(szFullName,szDirName);
- if ( strcmp(szDirName,"/") ) (void)strcat(szFullName,"/");
- (void)strcat(szFullName,szEntry);
- if ( stat(szFullName, &stb) < 0 ) {
- if ( errno == ENOENT ) { /* No such entry */
- if ( szEntry[0] == '.' && iFlagDot == FALSE ) {
- continue;
- }
- else {
- entry_store(ENTRY_FILE,szEntry,0,0,iNumFiles++);
- }
- }
- else {
- iReturn = TRUE;
- (void)sprintf(szError,"%s: %s",szProgName,szFullName);
- perror(szError);
- }
- }
- else {
- if ( S_ISDIR(stb.st_mode) ) { /* directory */
- if ( szEntry[0] == '.' && iFlagDot == FALSE ) {
- continue;
- }
- else {
- entry_store(ENTRY_DIR,szEntry,
- (int)stb.st_mtime,(int)stb.st_size,iNumDirs++);
- }
- }
- else { /* file */
- if ( szEntry[0] == '.' && iFlagDot == FALSE ) {
- continue;
- }
- else {
- entry_store(ENTRY_FILE,szEntry,
- (int)stb.st_mtime,(int)stb.st_size,iNumFiles++);
- }
- }
- iTemp = strlen(szEntry);
- if ( iTemp > iLongest ) iLongest = iTemp;
- }
- }
- }
- else iDone = TRUE;
- } while ( !iDone );
- return;
- }
-
- /**********************************************************************/
- void close_directory() /* close an opened directory */
- /**********************************************************************/
- {
- (void)closedir(dirp);
- return;
- }
-
- /**********************************************************************/
- int sort_name(entry1,entry2) /* qsort func, by entry name */
- /**********************************************************************/
- EntryData *entry1,
- *entry2;
- {
- return strcmp(entry1->szName,entry2->szName);
- }
-
- /**********************************************************************/
- int sort_rev_name(entry1,entry2) /* qsort func, by rev entry name */
- /**********************************************************************/
- EntryData *entry1,
- *entry2;
- {
- return strcmp(entry2->szName,entry1->szName);
- }
-
- /**********************************************************************/
- int sort_date_modified(entry1,entry2) /* qsort func, by date mod */
- /**********************************************************************/
- EntryData *entry1,
- *entry2;
- {
- return(entry2->iMod - entry1->iMod);
- }
-
- /**********************************************************************/
- int sort_rev_date_modified(entry1,entry2) /* qsort func, rev date mod */
- /**********************************************************************/
- EntryData *entry1,
- *entry2;
- {
- return(entry1->iMod - entry2->iMod);
- }
-
- /**********************************************************************/
- int sort_size(entry1,entry2) /* qsort func, by size */
- /**********************************************************************/
- EntryData *entry1,
- *entry2;
- {
- return(entry2->iSize - entry1->iSize);
- }
-
- /**********************************************************************/
- int sort_rev_size(entry1,entry2) /* qsort func, rev by size */
- /**********************************************************************/
- EntryData *entry1,
- *entry2;
- {
- return(entry1->iSize - entry2->iSize);
- }
-
- /**********************************************************************/
- void display_directory()
- /**********************************************************************
-
- display directory: "returns nothing"
-
- * shows pathname and entry qty if needed
- * shows file and dir count if needed
- * if using alternate output show column header
- * for each entry in the directory display its name
- * if using alternate output show the needed details
-
- **********************************************************************/
- {
- register int t,
- i;
- int iColCnt,
- iColWidth,
- iNblanks,
- iSpace = 3;
- char szPathName[MAX_NAME_LEN];
-
- iColWidth = iScrWidth / iNumColumns;
- iNumEntries = 0;
-
- if ( iFlagBrief && iFlagCount ) iFlagQty = TRUE;
- if ( !iFlagFiles && !iFlagDirs ) {
- iFlagFiles = TRUE;
- iFlagDirs = TRUE;
- }
- if ( iFlagFiles ) iNumEntries += iNumFiles;
- if ( iFlagDirs ) iNumEntries += iNumDirs;
- if ( !iFlagBrief ) (void)printf("\n");
- if ( iFlagPath ) display_header();
- if ( iNumFiles && iFlagFiles ) {
- iColCnt = 0;
- iNblanks = 0;
- if ( iFlagQty ) {
- if (iNumFiles == 1)
- (void)printf("%d File%c\n",iNumFiles,cQtyChar);
- else
- (void)printf("%d Files%c\n",iNumFiles,cQtyChar);
- if ( !iFlagBrief ) (void)printf("\n");
- }
- if ( !iFlagCount ) {
- if ( iFlagAltOutput ) { /* ALTERNATE OUTPUT FORMAT */
- if ( iFlagHeader ) {
- (void)printf("Name");
- align_column(iLongest,strlen("name"),iSpace);
- if ( iFlagInode ) (void)printf(" Inode # ");
- if ( iFlagLinkCnt ) (void)printf("Link Cnt ");
- if ( iFlagSize ) (void)printf("Size (bytes) ");
- if ( iFlagPro ) {(void)printf("User Group Other ");
- (void)printf(" User.Group ");}
- if ( iFlagAccessed ) (void)printf("Accessed ");
- if ( iFlagModified ) (void)printf("Modified ");
- if ( iFlagStatus ) (void)printf("Status Changed ");
- (void)printf("\n");
- repeat_char('-',iScrWidth-1); (void)printf("\n");
- }
- for ( t=0 ; t<iNumFiles ; ++t ) {
- if ( iFilesOnly ) (void)strcpy(szPathName,File[t].szName);
- else {
- (void)strcpy(szPathName,szDirName);
- if ( strcmp(szDirName,"/") ) (void)strcat(szPathName,"/");
- (void)strcat(szPathName,File[t].szName);
- }
- stat_file(File[t].szName,szPathName);
- }
- if ( !iFlagBrief ) (void)printf("\n");
- }
- else { /* DEFAULT FORMAT */
- for ( t=0 ; t<iNumFiles ; ++t ) {
- for ( i=0; i<iNblanks ; ++i ) (void)putchar(' ');
- (void)printf("%s",File[t].szName);
- if (++iColCnt >= iNumColumns) {
- (void)putchar('\n');
- iColCnt = 0;
- iNblanks = 0;
- }
- else iNblanks = iColWidth - strlen(File[t].szName);
- }
- if (iColCnt != 0) (void)putchar('\n');
- if ( !iFlagBrief ) (void)printf("\n");
- }
- }
- }
- if ( iNumDirs && iFlagDirs ) { /* DISPLAY DIRECTORIES */
- iColCnt = 0;
- iNblanks = 0;
- if ( iFlagQty ) { /* DISPLAY THE QTY OF DIRS FLAG */
- if (iNumDirs == 1)
- (void)printf("%d Directory%c\n",iNumDirs,cQtyChar);
- else
- (void)printf("%d Directories%c\n",iNumDirs,cQtyChar);
- if ( !iFlagBrief ) (void)printf("\n");
- }
- if ( !iFlagCount ) {
- if ( iFlagAltOutput ) { /* ALTERNATE OUTPUT FORMAT */
- if ( iFlagHeader ) {
- (void)printf("Name");
- align_column(iLongest,strlen("name"),iSpace);
- if ( iFlagInode ) (void)printf(" Inode # ");
- if ( iFlagLinkCnt ) (void)printf("Link Cnt ");
- if ( iFlagSize ) (void)printf("Size (bytes) ");
- if ( iFlagPro ) {(void)printf("User Group Other ");
- (void)printf(" User.Group ");}
- if ( iFlagAccessed ) (void)printf("Accessed ");
- if ( iFlagModified ) (void)printf("Modified ");
- if ( iFlagStatus ) (void)printf("Status Changed ");
- (void)printf("\n");
- repeat_char('-',iScrWidth-1); (void)printf("\n");
- }
- for ( t=0 ; t<iNumDirs ; ++t ) {
- (void)strcpy(szPathName,szDirName);
- if ( strcmp(szDirName,"/") )
- (void)strcat(szPathName,(char *)"/");
- (void)strcat(szPathName,Dir[t].szName);
- stat_file(Dir[t].szName,szPathName);
- }
- if ( !iFlagBrief ) (void)printf("\n");
- }
- else { /* DEFAULT FORMAT */
- for ( t=0 ; t<iNumDirs ; ++t ) {
- for ( i=0 ; i<iNblanks ; ++i ) (void)putchar(' ');
- (void)printf("%s",Dir[t].szName);
- if (++iColCnt >= iNumColumns) {
- (void)putchar('\n');
- iColCnt = 0;
- iNblanks = 0;
- }
- else iNblanks = iColWidth - strlen(Dir[t].szName);
- }
- if (iColCnt != 0) (void)putchar('\n');
- if ( !iFlagBrief ) (void)printf("\n");
- }
- }
- }
- return;
- }
-
- /**********************************************************************/
- void stat_file(szFileName,szPathName)
- /**********************************************************************
-
- stat file: "returns nothing"
-
- * receives the file name and the path name
- * calls the system stat() function
- * depending on the flags, various information is displayed
-
- **********************************************************************/
- char *szFileName,
- *szPathName;
- {
- int iLink,
- iSpace = 3,
- iValidFile = TRUE;
- char szError[MAX_ERROR_LEN],
- szLinkName[MAX_NAME_LEN];
-
- szLinkName[0] = '\0';
- if ( lstat(szPathName, &stb) < 0 ) {
- iReturn = TRUE;
- (void)sprintf(szError,"%s: %s",szProgName,szPathName);
- perror(szError);
- }
- else {
-
- #ifndef SVR3
- if ( S_ISLNK(stb.st_mode) )
- if ( (iLink = readlink(szPathName,szLinkName,MAX_NAME_LEN)) )
- szLinkName[iLink] = '\0';
- #endif
-
- if ( iFlagLink ) {
- (void)printf("%s",szFileName);
- if ( iLongest >= strlen("Name") )
- align_column(iLongest,strlen(szFileName),iSpace);
- else
- align_column(strlen("Name"),strlen(szFileName),iSpace);
- display_expanded(szLinkName, iValidFile);
- (void)printf("\n");
- }
- else {
- if ( stat(szPathName, &stb) < 0 ) {
- if ( errno == ENOENT ) {
- iValidFile = FALSE;
- (void)printf("%s",szFileName);
- if ( iLongest >= strlen("Name") )
- align_column(iLongest,strlen(szFileName),iSpace);
- else
- align_column(strlen("Name"),strlen(szFileName),iSpace);
- display_expanded(szLinkName, iValidFile);
- (void)printf("\n");
- }
- else {
- iReturn = TRUE;
- (void)sprintf(szError,"%s: %s",szProgName,szPathName);
- perror(szError);
- }
- }
- else {
- (void)printf("%s",szFileName);
- if ( iLongest >= strlen("Name") )
- align_column(iLongest,strlen(szFileName),iSpace);
- else
- align_column(strlen("Name"),strlen(szFileName),iSpace);
- display_expanded(szLinkName, iValidFile);
- (void)printf("\n");
- }
- }
- }
- return;
- }
-
- /**********************************************************************/
- void display_expanded(szLinkName, iValid)
- /**********************************************************************
-
- display expanded: "returns nothing"
-
- * this is used only for alternate outputs
- * depending on various flags, different sections are used
-
- **********************************************************************/
- char *szLinkName;
- int iValid;
- {
- int iHour, iMin, iSec, iMonth, iDay, iYear;
- if ( iValid ) {
- if ( iFlagInode ) (void)printf("%7ld ",stb.st_ino);
- if ( iFlagLinkCnt ) (void)printf("%6d ",stb.st_nlink);
- if ( iFlagSize ) {
- if ( S_ISCHR(stb.st_mode) || S_ISBLK(stb.st_mode) ) {
- (void)printf(" %3u, %3u ",
- major(stb.st_rdev),minor(stb.st_rdev));
- }
- else {
- (void)printf("%12ld ",stb.st_size);
- }
- }
- if ( iFlagPro ) {
- if ( stb.st_mode & S_IRUSR ) (void)printf("r");
- else (void)printf("-");
- if ( stb.st_mode & S_IWUSR ) (void)printf("w");
- else (void)printf("-");
- if ( stb.st_mode & S_ISUID ) {
- (void)printf("S");
- }
- else {
- if ( stb.st_mode & S_IXUSR ) (void)printf("x");
- else (void)printf("-");
- }
- (void)printf(" ");
- if ( stb.st_mode & S_IRGRP ) (void)printf("r");
- else (void)printf("-");
- if ( stb.st_mode & S_IWGRP ) (void)printf("w");
- else (void)printf("-");
- if ( stb.st_mode & S_ISGID ) {
- (void)printf("S");
- }
- else {
- if ( stb.st_mode & S_IXGRP ) (void)printf("x");
- else (void)printf("-");
- }
- (void)printf(" ");
- if ( stb.st_mode & S_IROTH ) (void)printf("r");
- else (void)printf("-");
- if ( stb.st_mode & S_IWOTH ) (void)printf("w");
- else (void)printf("-");
- if ( stb.st_mode & S_IXOTH ) (void)printf("x");
- else (void)printf("-");
- (void)printf(" ");
- passwdp = (struct passwd *)getpwuid((int)stb.st_uid);
- if ( passwdp != NULL ) (void)printf("%8s.",passwdp->pw_name);
- else (void)printf("%8d.",stb.st_uid);
- groupp = (struct group *)getgrgid((int)stb.st_gid);
- if ( groupp != NULL ) (void)printf("%-8s",groupp->gr_name);
- else (void)printf("%-8d",stb.st_gid);
- (void)printf(" ");
- }
- if ( iFlagAccessed ) {
- tmp = localtime(&stb.st_atime);
- iHour = tmp->tm_hour; iMin = tmp->tm_min; iSec = tmp->tm_sec;
- iMonth = tmp->tm_mon+1; iDay = tmp->tm_mday; iYear = tmp->tm_year;
- if ( iMonth < 10 ) (void)printf("0%1d/",iMonth);
- else (void)printf("%2d/",iMonth);
- if ( iDay < 10 ) (void)printf("0%1d/",iDay);
- else (void)printf("%2d/",iDay);
- if ( iYear < 10 ) (void)printf("0%1d",iYear);
- else (void)printf("%2d",iYear);
- (void)printf("-");
- if ( iHour < 10 ) (void)printf("0%1d:",iHour);
- else (void)printf("%2d:",iHour);
- if ( iMin < 10 ) (void)printf("0%1d:",iMin);
- else (void)printf("%2d:",iMin);
- if ( iSec < 10 ) (void)printf("0%1d",iSec);
- else (void)printf("%2d",iSec);
- (void)printf(" ");
- }
- if ( iFlagModified ) {
- tmp = localtime(&stb.st_mtime);
- iHour = tmp->tm_hour; iMin = tmp->tm_min; iSec = tmp->tm_sec;
- iMonth = tmp->tm_mon+1; iDay = tmp->tm_mday; iYear = tmp->tm_year;
- if ( iMonth < 10 ) (void)printf("0%1d/",iMonth);
- else (void)printf("%2d/",iMonth);
- if ( iDay < 10 ) (void)printf("0%1d/",iDay);
- else (void)printf("%2d/",iDay);
- if ( iYear < 10 ) (void)printf("0%1d",iYear);
- else (void)printf("%2d",iYear);
- (void)printf("-");
- if ( iHour < 10 ) (void)printf("0%1d:",iHour);
- else (void)printf("%2d:",iHour);
- if ( iMin < 10 ) (void)printf("0%1d:",iMin);
- else (void)printf("%2d:",iMin);
- if ( iSec < 10 ) (void)printf("0%1d",iSec);
- else (void)printf("%2d",iSec);
- (void)printf(" ");
- }
- if ( iFlagStatus ) {
- tmp = localtime(&stb.st_ctime);
- iHour = tmp->tm_hour; iMin = tmp->tm_min; iSec = tmp->tm_sec;
- iMonth = tmp->tm_mon+1; iDay = tmp->tm_mday; iYear = tmp->tm_year;
- if ( iMonth < 10 ) (void)printf("0%1d/",iMonth);
- else (void)printf("%2d/",iMonth);
- if ( iDay < 10 ) (void)printf("0%1d/",iDay);
- else (void)printf("%2d/",iDay);
- if ( iYear < 10 ) (void)printf("0%1d",iYear);
- else (void)printf("%2d",iYear);
- (void)printf("-");
- if ( iHour < 10 ) (void)printf("0%1d:",iHour);
- else (void)printf("%2d:",iHour);
- if ( iMin < 10 ) (void)printf("0%1d:",iMin);
- else (void)printf("%2d:",iMin);
- if ( iSec < 10 ) (void)printf("0%1d",iSec);
- else (void)printf("%2d",iSec);
- (void)printf(" ");
- }
- }
- else {
- (void)printf("(Broken Link) destination doesn't exist: ");
- }
- if ( strlen(szLinkName) ) {
- if ( iFlagLink ) (void)printf("(Link Status)");
- else (void)printf("-> %s",szLinkName);
- }
- return;
- }
-
- /**********************************************************************/
- void align_column(iLong,iCurrent,iGap) /* pad stdout to align column */
- /**********************************************************************/
- int iLong,
- iCurrent,
- iGap;
- {
- register int i,
- t;
- t = iLong - iCurrent;
- for ( i=0 ; i<t ; i++ ) (void)putchar(' ');
- for ( i=0 ; i<iGap ; i++ ) (void)putchar(' ');
- return;
- }
-
- /**********************************************************************/
- void repeat_char(cChar,iQty) /* repeat a char in a string */
- /**********************************************************************/
- char cChar;
- register int iQty;
- {
- register int i;
- for ( i=0 ; i<iQty ; i++ ) (void)putchar(cChar);
- return;
- }
-
- /**********************************************************************/
- void program_usage()
- /**********************************************************************/
- {
- (void)printf("\n");
- (void)printf("Usage: %s <options> <list of files/dirs>\n",szProgName);
- return;
- }
-
- /**********************************************************************/
- void program_help()
- /**********************************************************************/
- {
- (void)printf(
- " -a | -all ... show all entries ( include '.' & '..' ).\n");
- (void)printf(
- " -b | -brief ... same as '-nh -np -nq' & no blank lines.\n");
- (void)printf(
- " -c | -count ... show counts only.\n");
- (void)printf(
- " -d | -dir ... directories only.\n");
- (void)printf(
- " -f | -file ... files only.\n");
- (void)printf(
- " -h | -help ... help information.\n");
- (void)printf(
- " -i | -inode ... show file inode number.\n");
- #ifndef SVR3
- (void)printf(
- " -l | -link ... if symbolic link, show links status\n");
- #endif
- (void)printf(
- " -p | -pro ... file protection (user,group,other).\n");
- (void)printf(
- " -r | -reverse ... sort entries in reverse order.\n");
- (void)printf(
- " -s | -size ... file size.\n");
- (void)printf(
- " -v | -version ... version stamp.\n");
- (void)printf(
- " -w | -wide ... wide format output ( 132 columns ).\n");
- (void)printf(
- " -lc | -link_cnt ... hard link count.\n");
- (void)printf(
- " -nd | -no_dot ... don't show files that start with '.'.\n");
- (void)printf(
- " -nh | -no_hdr ... don't show header on extended output.\n");
- (void)printf(
- " -np | -no_pwd ... don't show pathname.\n");
- (void)printf(
- " -nq | -no_qty ... don't show quantities.\n");
- (void)printf(
- " -ns | -no_sort ... don't sort the files/directories.\n");
- (void)printf(
- " -sc | -sglcol ... force single column output.\n");
- (void)printf(
- " -sm | -sort_dtm ... sort by date modified.\n");
- (void)printf(
- " -ss | -sort_size ... sort by file size.\n");
- (void)printf(
- " -det | -detail ... all date/time options.\n");
- (void)printf(
- " -dta | -accessed ... date/time accessed.\n");
- (void)printf(
- " -dtm | -modified ... date/time modified.\n");
- (void)printf(
- " -dts | -status ... date/time status changed.\n");
- program_usage();
- return;
- }
-
- /**********************************************************************/
- void program_version()
- /**********************************************************************/
- {
- (void)printf(
- "[ print directory (pd) Scott L. Fehrman version (%s)]\n"
- ,VERSION);
- return;
- }
-
- #ifdef SVR3
- /**********************************************************************/
- int lstat() /*** this is a dumb function if using SVR3 UNIX system ***/
- /**********************************************************************/
- {
- return(0);
- }
- #endif
-