fsize#

fsize.c

/* Print File Sizes */
#include<stdio.h>
#include<string.h>
#include<fcntl.h>   /* flags for read and write */
#include<sys/types.h>   /* typedefs */
#include<sys/stat.h>    /* structure returned by stat */
#include "dirent.h"

void fsize(char *);

/* print file sizes */
int main(int argc,char **argv)
{
    if(argc == 1)   /* default : current directory */
        fsize(".");
    else
        while(--argc > 0)
            fsize(*++argv);
    return 0;
}

int stat(char *,struct stat *);
void dirwalk(char *,void (*fcn)(char *));

/* fsize: print size of file "name" */
void fsize(char *name)
{
    struct stat stbuf;
    
    if(stat(name,&stbuf) == -1)
    {
        fprintf(stderr,"fsize: Can't access %s \n",name);
        return;
    }
    if((stbuf.st_mode & S_IFMT) == S_IFDIR)
        dirwalk(name,fsize);
    printf("%8ld %s \n",stbuf.st_size,name);
}


#define MAX_PATH 1024

/* dirwalk: apply fcn to all files in dir */
void dirwalk(char *dir,void (*fcn)(char *))
{
    char name[MAX_PATH];
    Dirent *dp;
    DIR *dfd;

    if((dfd = opendir(dir)) == NULL)
    {
        fprintf(stderr,"dirwalk: can't open %s\n",dir);
        return;
    }

    while((dp = readdir(dfd)) != NULL)
    {
        if(strcmp(dp->name,".") == 0 || strcmp(dp->name,"..") == 0)
            continue;
        if(strlen(dir)+strlen(dp->name)+2 > sizeof(name)) 
            fprintf(stderr,"dirwalk: name %s/ %s too long \n",dir,dp->name);
        else
        {
            sprintf(name,"%s/%s",dir,dp->name);
            (*fcn)(name);
        }
    }
    closeddir(dfd);
}


#ifndef DIRSIZ
#define DIRSIZ 14
#endif

struct direct   /* directory entry */
{
    ino_t d_ino;    /* inode number */
    char d_name[DIRSIZ];    /* long name does not have '\0' */
};

int fstat(int fd,struct stat *);

/* opendir: open a directory for readdir calls */

DIR *opendir(char *dirname)
{
    int fd;
    struct stat stbuf;
    DIR *dp;
    
    if((fd = open(dirname,O_RDONLY,0)) == -1
        || fstat(fd,&stbuf) == -1
        || (stbuf.st_mode & S_IFMT) != S_IFDIR
        || (dp = (DIR *)malloc(sizeof(DIR))) == NULL)
        return NULL;
    dp->fd = fd;
    return dp;
}

/* closedir: close directory opened by opendir */
void closedir(DIR *dp)
{
    if(dp)
    {
        close(dp->fd);
        free(dp);
    }
}


#include<sys/dir.h> /* local directory structure */
/* readdir: read directory entries in sequence */

Dirent *readdir(DIR *dp)
{
    struct direct dirbuf;   /* local directory structure */
    static Dirent d;    /* return: portable structure */
    
    while(read(dp->fd,(char *)&dirbuf,sizeof(dirbuf)) == sizeof(dirbuf))
    {
        if(dirbuf.d_ino= 0)
            continue;
        d.ino = dirbuf.d_ino;
        strncpy(d.name,dirbuf.d_name,DIRSIZ);
        d.name[DIRSIZ] = '\0';
        return &d;
    }

    return NULL;
}