I am writing a program to print filenames in the current directory and print the time stamps next to them. I am loading the names into an array and then passing them to a function to print the stat and filenames. Here is the code.

#include <stdio.h>           /* For printf, fprintf */
#include <string.h>          /* For strcmp */
#include <ctype.h>           /* For isdigit */
#include <fcntl.h>           /* For O_RDONLY */
#include <dirent.h>      /* For getdents */
#include <sys/stat.h>        /* For IS macros */
#include <sys/types.h>       /* For modet */
#include <time.h>            /* For localtime, asctime */


/* #define Statements */
#define MAX_FILES            100
#define MAX_FILENAME         50
#define NOT_FOUND            -1
#define FOREVER              -1
#define DEFAULT_DELAY_TIME   10
#define DEFAULT_LOOP_COUNT   FOREVER


/* Booleans */
enum { FALSE, TRUE };


/* Status structure, one per file. */
struct statStruct
 {
   char fileName [MAX_FILENAME]; /* File name */
   int lastCycle, thisCycle; /* To detect changes */
   struct stat status; /* Information from stat () */
 };


/* Globals */
char* fileNames [MAX_FILES]; /* One per file on command line */
int fileCount; /* Count of files on command line */
struct statStruct stats [MAX_FILES]; /* One per matching file */
int loopCount = DEFAULT_LOOP_COUNT; /* Number of times to loop */
int delayTime = DEFAULT_DELAY_TIME; /* Seconds between loops */

/****************************************************************/

main (int argc,char* argv[])
{
 parseCommandLine (argc, argv); /* Parse command line */
 monitorLoop (); /* Execute main monitor loop */
 return (/* EXIT_SUCCESS */ 0);
}

/****************************************************************/

parseCommandLine (int argc,char* argv[])
/* Parse command line arguments */

{
 DIR *dp;
 struct dirent *dirEntry;
 char fileName [MAX_FILENAME];
 fileCount = 0;
 int i;
 dp = opendir (".");
 if (dp == NULL) fatalError();
  while (dirEntry=readdir(dp)) /* Read all directory entries */
    {
                if((fnmatch("*c", dirEntry->d_name,0)) == 0)

       fileNames[fileCount++] = dirEntry->d_name ;
   }
        closedir(dp);
 if (fileCount == 0) usageError ();
}

/****************************************************************/


usageError ()

{
  fprintf (stderr, "Usage: myls <Search-Pattern>");
  exit (/* EXIT_FAILURE */ 1);
}

/****************************************************************/

monitorLoop ()

/* The main monitor loop */

{
      monitorFiles (); /* Scan all files */
      fflush (stdout); /* Flush standard output */
      fflush (stderr); /* Flush standard error */
}

/****************************************************************/

monitorFiles ()

/* Process all files */

{
  int i;

  for (i = 0; i < fileCount; i++)
    monitorFile (fileNames[i]);

}

/****************************************************************/

monitorFile (char* fileName)
/* Process a single file/directory*/

{
  struct stat statBuf;
  mode_t mode;
  int result;

  result = stat (fileName, &statBuf); /* Obtain file status */


  mode = statBuf.st_mode; /* Mode of file */

  if(S_ISDIR (mode)) /* Directory */
    printf("D%s", fileName);
  else if (S_ISREG (mode) || S_ISCHR (mode) || S_ISBLK (mode))
    updateStat (fileName, &statBuf); /* Regular file */
}

/****************************************************************/


updateStat (char* fileName,struct stat* statBuf)
/* Add a status entry if necessary */

{


     addEntry (fileName, statBuf); /* Add new entry */

}

/****************************************************************/


addEntry (char* fileName,struct stat* statBuf)

/* Add a new entry into the status array */

{
  int index;

  index = nextFree (); /* Find the next free entry */
  if (index == NOT_FOUND) return (NOT_FOUND); /* None left */
  strcpy (stats[index].fileName, fileName); /* Add filename */
  stats[index].status = *statBuf; /* Add status information */
  printEntry (index); /* Display status information */
  return (index);
}

/****************************************************************/

nextFree ()

/* Return the nextfree index in the status array */

{
  int i;

  for (i = 0; i < MAX_FILES; i++)
     return (i);

}

/****************************************************************/


printEntry (int index)
/* Display an entry of the status array */

{
  printf ("%s", stats[index].fileName);
  printStat (&stats[index].status);
}

/****************************************************************/

printStat (struct stat* statBuf)
/* Display a status buffer */

{
  printf ("\t\t\t %s",
           asctime (localtime (&statBuf->st_mtime)));
}

/****************************************************************/

fatalError ()

{
  perror ("monitor: ");
  exit (/* EXIT_FAILURE */ 1);
}

Okay... that's nice.

did you have a question?

LOL.. Yes.. SOrry.. It keep printing a lot of junk instead of filenames.. And then sometimes it prints the filenames... I'm having toruble figuring out why...

probably line 66: fileNames[fileCount++] = dirEntry->d_name ; you can't just assign strings like that. use strcpy() or something similar.

could be other problems, that just jumped out at me.

Hmmmm.. Now its saying segmentation fault

That's not a surprise!

struct dirent *dirEntry;

That's a pointer to some structure of type direct, but you do not set any memory apart before trying to access it and assigning to it.

On top of that, there are plenty of warnings that the compiler picks.

printfile.c:43: warning: return type defaults to `int'
printfile.c: In function `main':
printfile.c:44: warning: implicit declaration of function `parseCommandLine'
printfile.c:45: warning: implicit declaration of function `monitorLoop'
printfile.c: At top level:
printfile.c:54: warning: return type defaults to `int'
printfile.c: In function `parseCommandLine':
printfile.c:59: warning: ISO C90 forbids mixed declarations and code
printfile.c:61: warning: implicit declaration of function `fatalError'
printfile.c:62: warning: suggest parentheses around assignment used as truth value
printfile.c:64: warning: implicit declaration of function `fnmatch'
printfile.c:69: warning: implicit declaration of function `usageError'
printfile.c:57: warning: unused variable `fileName'
printfile.c:59: warning: unused variable `i'
printfile.c:70: warning: control reaches end of non-void function
printfile.c: At top level:
printfile.c:77: warning: return type defaults to `int'
printfile.c: In function `usageError':
printfile.c:79: warning: implicit declaration of function `exit'
printfile.c: At top level:
printfile.c:88: warning: return type defaults to `int'
printfile.c: In function `monitorLoop':
printfile.c:89: warning: implicit declaration of function `monitorFiles'
printfile.c:92: warning: control reaches end of non-void function
printfile.c: At top level:
printfile.c:100: warning: return type defaults to `int'
printfile.c: In function `monitorFiles':
printfile.c:104: warning: implicit declaration of function `monitorFile'
printfile.c:106: warning: control reaches end of non-void function
printfile.c: At top level:
printfile.c:113: warning: return type defaults to `int'
printfile.c: In function `monitorFile':
printfile.c:126: warning: implicit declaration of function `updateStat'
printfile.c:127: warning: control reaches end of non-void function
printfile.c: At top level:
printfile.c:135: warning: return type defaults to `int'
printfile.c: In function `updateStat':
printfile.c:138: warning: implicit declaration of function `addEntry'
printfile.c:140: warning: control reaches end of non-void function
printfile.c: At top level:
printfile.c:149: warning: return type defaults to `int'
printfile.c: In function `addEntry':
printfile.c:152: warning: implicit declaration of function `nextFree'
printfile.c:156: warning: implicit declaration of function `printEntry'
printfile.c: At top level:
printfile.c:166: warning: return type defaults to `int'
printfile.c: In function `nextFree':
printfile.c:172: warning: control reaches end of non-void function
printfile.c: At top level:
printfile.c:180: warning: return type defaults to `int'
printfile.c: In function `printEntry':
printfile.c:182: warning: implicit declaration of function `printStat'
printfile.c:183: warning: control reaches end of non-void function
printfile.c: At top level:
printfile.c:190: warning: return type defaults to `int'
printfile.c: In function `printStat':
printfile.c:193: warning: control reaches end of non-void function
printfile.c: At top level:
printfile.c:199: warning: return type defaults to `int'
C:\Users\NONAME\AppData\Local\Temp/ccdRgMeX.o:printfile.c:(.text+0xa0): undefined reference to `fnmatch'

Edited 6 Years Ago by Aia: n/a

That's not a surprise!

struct dirent *dirEntry;

That's a pointer to some structure of type direct, but you do not set any memory apart before trying to access it and assigning to it.

On top of that, there are plenty of warnings that the compiler picks.

Oh ok... But the compiler only gave me the segmentation fault when using strcpy(). When I assign it just prints out some files name... And the rest garbage... Any code modifications would be helpful :)

Oh ok... But the compiler only gave me the segmentation fault when using strcpy(). When I assign it just prints out some files name... And the rest garbage... Any code modifications would be helpful :)

Sure, before you were just accessing wherever dirEntry->d_name points to, now with strcpy() you are trying to modify wherever that memory is, and that's not good.

Most of the warnings are because you decided not to explicitly define your functions with a type return.
e.i.
If you don't care about returning anything it should be void

void usageError ()
{
    fprintf (stderr, "Usage: myls <Search-Pattern>");

    exit (/* EXIT_FAILURE */ 1);
}

exit() requires the header file stdlib.h to be included.
What else?, yes a couple variables never get used.
It doesn't know what fnmatch() is.

Edited 6 Years Ago by Aia: n/a

This article has been dead for over six months. Start a new discussion instead.