#!/usr/bin/perl -w

use Inline C => Config => CCFLAGS => '-Wall';

use Inline C;

map +{ print "$_\n" } , list_dir("/var");

__END__
__C__
  
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#define errorMsg printf
#define follow_links 0

struct dnode {                          /* the basic node */
    char *name;                         /* the dir entry name */
    char *fullname;                     /* the dir entry name */
    struct stat dstat;          /* the file stat info */
    struct dnode *next;         /* point at the next node */
};

typedef struct dnode dnode_t;

/* This code was mostly copied from busybox-0.47, GPL applies */
void list_dir( char *path) {
  struct dnode node;
  struct dirent *entry;
  DIR *dir;
  char *fnend, fullname[BUFSIZ+1] ;
  Inline_Stack_Vars;


  if (path==NULL) return;//(NULL);
  strcpy(fullname, path);
  fnend = fullname + strlen(fullname);
  if (fnend[-1] != '/') {
    strcat(fullname, "/");
    fnend++;
  }
  
  dir = opendir(fullname);
  if (dir == NULL) {
    errorMsg("%s: %s\n", fullname, strerror(errno));
    Inline_Stack_Done;
    return;
  }

  Inline_Stack_Reset;
  while ((entry = readdir(dir)) != NULL) {
    /* are we going to list the file- it may be . or .. or a hidden */
    strcpy(fnend, entry->d_name);
    if (follow_links == TRUE) {
      if (stat(fullname, &node.dstat)) {
	errorMsg("%s: %s\n", fullname, strerror(errno));
	continue;
      }
    } else

      if (lstat(fullname, &node.dstat)) {   /* get file stat info into */
	errorMsg("%s: %s\n", fullname, strerror(errno));
	continue;
      }
    Inline_Stack_Push(newSVpv(fullname,0));
  }
  closedir(dir);
  Inline_Stack_Done;
}

