LNXdev.com

List Directory

Show files located in a directory

This is very similar program to 'ls' found in Coreutils that ships with every Linux distribution. It's not meant to replace 'ls' by any means. But if your curious about how it can be done, read further.

Compile source code with gcc

$ gcc list.c -o list

Execute the program:

$ ./list /path/to/folder/

Remember that last backlash(/), the program won't work as intended if omitted.

/* program to list all files in a given folder */

#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

struct entry {
  struct entry *prev;
  char name[255]; /* maximum filename length usualy 256 characters */
  int sizeB;
  struct entry *next;
};

struct entry *begin = (struct entry *) 0; /* Pointers to the beginning and */
struct entry *end = (struct entry *) 0;  /* the end of the list */

/* all the filenames and directories are put in a linked list */
struct entry *appendEntry(struct entry *add)
{
  if(begin == NULL) {
    begin = add;
    add->prev = begin;
  }
  else {
    end->next = add;
    add->prev = end;
  }
  end = add;
  add->next = NULL;

  return add;
}

/* allocate space for each entry  */
struct entry *initEntry(char *filename, char *path)
{
  struct entry *ptr;
  ptr = (struct entry *) calloc( 1, sizeof(struct entry) );
  if( ptr == NULL)
    return (struct entry *) 0;
  else {
    // add name to structure
    strcpy(ptr->name, filename);
    // add filesize to structure
    ptr->sizeB = getFileSize(ptr->name, path);
    return ptr;
  }
}

/* this fuction travereses through the list and prints its contents */
void printList (struct entry *list)
{
  while(list != (struct entry *) 0) {
    printf("%-32s", list->name); /* file or directory name */
    printf("%i\n", list->sizeB); /* filesize or linksize if a directory */
    list = list->next;
  }
}


/* get filenames and return pointer to first */
void readDirectory(char *path) 
{ 
  DIR *dirPtr;
  struct dirent *entity;

  dirPtr = opendir(path); /* dirPtr points to path from command line */
  /* testing that the directory exists */
  if (!dirPtr) {
    printf("%s\n", path);
    printf("Directory not found.\n");
    exit(1);
  }
  errno = 0;
  /* read through directory as long as there are entries */
  while ((entity=readdir(dirPtr))) {
    appendEntry(initEntry(entity->d_name, path));
  }
  /* in case something went wrong */
  if(errno) {
    printf("Failed to process directory\n");
    exit(1);
  }
  /* don't forget to close the directory */
  closedir(dirPtr);
}

/* get input from terminal */
/* which we actually don't need for anything in this program... */
void readline (char *charPtr)
{
  do
  {
    *charPtr = getchar();
    charPtr++;
  }
  while (*(charPtr - 1) != '\n');
  *charPtr = '\0';
}

/* calculate filesize, second parameter pwd stands for present working directory */
int getFileSize (char *filename, char *pwd)
{
  int i = 0, j, k;
  int size = 0;
  struct stat buffer; //sys/stat
  char path[255];

  strcpy(path, pwd);
  strcat(path, filename);

  i = stat(path, &buffer); /* stat structure hold alot of information about the file
                              or folder, we are using this to get the filesize */

  if(i < 0)
    perror(path);
  else
    size = buffer.st_size;
  errno = 0;
  return size;
}

int main (int argc, char *argv[])
{
  char *pwd = argv[1]; //present working directory

  // test for path
  if (argc < 2) {
    printf("No path given\n");
    return 0;
  }
  
  // read filenames and size and put in a doubly linked list
  readDirectory(argv[1]);

  printf("Filename                        Size\n");
  printf("------------------------------------\n");
  printList(begin); //print linked list

  // free memory
  free(begin);
  return 0;
}