From 103b7e031c4de0f9753e02d2217aa81819242278 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 4 Oct 2007 02:04:10 -0500 Subject: Break out dirtree.c and let it call a function instead of returning the data. --- lib/dirtree.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/lib.c | 62 ---------------------------------------------- lib/lib.h | 13 ++++++---- toys/mke2fs.c | 18 ++++++++++---- 4 files changed, 100 insertions(+), 72 deletions(-) create mode 100644 lib/dirtree.c diff --git a/lib/dirtree.c b/lib/dirtree.c new file mode 100644 index 00000000..b64dfaf5 --- /dev/null +++ b/lib/dirtree.c @@ -0,0 +1,79 @@ +/* vi: set sw=4 ts=4 :*/ +/* dirtree.c - Functions for dealing with directory trees. + * + * Copyright 2007 Rob Landley + */ + +#include "toys.h" + +// Create a dirtree node from a path. + +struct dirtree *dirtree_add_node(char *path) +{ + struct dirtree *dt; + char *name; + + // Find last chunk of name. + + for (;;) { + name = strrchr(path, '/'); + + if (!name) name = path; + else { + if (*(name+1)) name++; + else { + *name=0; + continue; + } + } + break; + } + + dt = xzalloc(sizeof(struct dirtree)+strlen(name)+1); + xstat(path, &(dt->st)); + strcpy(dt->name, name); + + return dt; +} + +// Given a directory (in a writeable PATH_MAX buffer), recursively read in a +// directory tree. +// +// If callback==NULL, allocate tree of struct dirtree and +// return root of tree. Otherwise call callback(node) on each hit, free +// structures after use, and return NULL. + +struct dirtree *dirtree_read(char *path, struct dirtree *parent, + int (*callback)(struct dirtree *node)) +{ + struct dirtree *dt = NULL, **ddt = &dt; + DIR *dir; + int len = strlen(path); + + if (!(dir = opendir(path))) perror_msg("No %s", path); + + for (;;) { + struct dirent *entry = readdir(dir); + if (!entry) break; + + // Skip "." and ".." + if (entry->d_name[0]=='.') { + if (!entry->d_name[1]) continue; + if (entry->d_name[1]=='.' && !entry->d_name[2]) continue; + } + + snprintf(path+len, sizeof(toybuf)-len, "/%s", entry->d_name); + *ddt = dirtree_add_node(path); + (*ddt)->parent = parent; + if (callback) callback(*ddt); + if (entry->d_type == DT_DIR) + (*ddt)->child = dirtree_read(path, *ddt, callback); + if (callback) free(*ddt); + else ddt = &((*ddt)->next); + path[len]=0; + } + + return dt; +} + + diff --git a/lib/lib.c b/lib/lib.c index 64c85698..7cb29f8f 100644 --- a/lib/lib.c +++ b/lib/lib.c @@ -549,65 +549,3 @@ void xpidfile(char *name) xwrite(fd, spid, sprintf(spid, "%ld\n", (long)getpid())); close(fd); } - -// Create a dirtree node from a path. - -struct dirtree *read_dirtree_node(char *path) -{ - struct dirtree *dt; - char *name; - - // Find last chunk of name. - - for (;;) { - name = strrchr(path, '/'); - - if (!name) name = path; - else { - if (*(name+1)) name++; - else { - *name=0; - continue; - } - } - break; - } - - dt = xzalloc(sizeof(struct dirtree)+strlen(name)+1); - xstat(path, &(dt->st)); - strcpy(dt->name, name); - - return dt; -} - -// Given a directory (in a writeable PATH_MAX buffer), recursively read in a -// directory tree. - -struct dirtree *read_dirtree(char *path, struct dirtree *parent) -{ - struct dirtree *dt = NULL, **ddt = &dt; - DIR *dir; - int len = strlen(path); - - if (!(dir = opendir(path))) perror_msg("No %s", path); - - for (;;) { - struct dirent *entry = readdir(dir); - if (!entry) break; - - // Skip "." and ".." - if (entry->d_name[0]=='.') { - if (!entry->d_name[1]) continue; - if (entry->d_name[1]=='.' && !entry->d_name[2]) continue; - } - - snprintf(path+len, sizeof(toybuf)-len, "/%s", entry->d_name); - *ddt = read_dirtree_node(path); - (*ddt)->parent = parent; - if (entry->d_type == DT_DIR) (*ddt)->child = read_dirtree(path, *ddt); - ddt = &((*ddt)->next); - path[len]=0; - } - - return dt; -} diff --git a/lib/lib.h b/lib/lib.h index 37a94a53..4cc2dac4 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -21,16 +21,21 @@ struct arg_list { char *arg; }; +// args.c +void get_optflags(void); + +// dirtree.c struct dirtree { struct dirtree *next, *child, *parent; struct stat st; char name[]; }; -// args.c -void get_optflags(void); +struct dirtree *dirtree_add_node(char *path); +struct dirtree *dirtree_read(char *path, struct dirtree *parent, + int (*callback)(struct dirtree *node)); -// functions.c +// lib.c #if !defined(__UCLIBC__) && !defined(__KLIBC__) void strlcpy(char *dest, char *src, size_t size); #endif @@ -72,8 +77,6 @@ char *itoa(int n); long atolx(char *c); off_t fdlength(int fd); char *xreadlink(char *name); -struct dirtree *read_dirtree_node(char *path); -struct dirtree *read_dirtree(char *path, struct dirtree *parent); // getmountlist.c struct mtab_list { diff --git a/toys/mke2fs.c b/toys/mke2fs.c index 30612ee8..b102a2fe 100644 --- a/toys/mke2fs.c +++ b/toys/mke2fs.c @@ -7,6 +7,7 @@ #include "toys.h" +// Shortcut to our global data structure, since we use it so much. #define TT toy.mke2fs #define INODES_RESERVED 10 @@ -26,13 +27,16 @@ static uint32_t file_blocks_used(uint64_t size, uint32_t *blocklist) uint32_t dblocks = (uint32_t)((size+(TT.blocksize-1))/TT.blocksize); uint32_t idx=TT.blocksize/4, iblocks=0, diblocks=0, tiblocks=0; - // Fill out index blocks. + // Fill out index blocks in inode. if (blocklist) { int i; + // Direct index blocks for (i=0; i<13 && i 13+idx) blocklist[13] = 13+idx; + // Doubly indirect index blocks idx = 13 + idx + (idx*idx); if (dblocks > idx) blocklist[14] = idx; @@ -131,7 +135,7 @@ static void check_treelinks(struct dirtree *tree) // On the other hand, we have 128 bits to come up with a unique identifier, of // which 6 have a defined value. /dev/urandom it is. -static void fake_uuid(char *uuid) +static void create_uuid(char *uuid) { // Read 128 random bits int fd = xopen("/dev/urandom", O_RDONLY); @@ -206,7 +210,7 @@ static void init_superblock(struct ext2_superblock *sb) sb->feature_incompat = SWAP_LE32(EXT2_FEATURE_INCOMPAT_FILETYPE); sb->feature_ro_compat = SWAP_LE32(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER); - fake_uuid(sb->uuid); + create_uuid(sb->uuid); // TODO If we're called as mke3fs or mkfs.ext3, do a journal. @@ -331,13 +335,17 @@ static void fill_inode(struct ext2_inode *in, struct dirtree *this) // in->faddr } +// Works like an archiver. +// The first argument is the name of the file to create. If it already +// exists, that size will be used. + int mke2fs_main(void) { int i, temp; off_t length; uint32_t usedblocks, usedinodes, dtiblk, dtbblk; struct dirtree *dti, *dtb; - + // Handle command line arguments. if (toys.optargs[1]) { @@ -363,7 +371,7 @@ int mke2fs_main(void) if (TT.gendir) { strncpy(toybuf, TT.gendir, sizeof(toybuf)); - dti = read_dirtree(toybuf, NULL); + dti = dirtree_read(toybuf, NULL, NULL); } else { dti = xzalloc(sizeof(struct dirtree)+11); strcpy(dti->name, "lost+found"); -- cgit v1.2.3